从外部访问 Template (模板)的控件、获取它的属性值
2018-01-29 21:42
411 查看
DataTemplate 和 ControlTemplate 两个类均派生自 FrameWorkTemplate类。这个类有个 FindName方法 供我们查询内部控件。
ControlTemplate 对象: 访问其目标控件 Template . [b]FindName就能拿到。[/b]
DataTemplate 对象: 直接使用低层数据(如果想获得控件长度、宽度 [b]Template . FindName)。[/b]
<Window x:Class="AutomaticConfigurationAPP.Window5"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window5" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="cTmp">
<StackPanel Background="Orange">
<TextBox x:Name="textbox1" Margin="6"/>
<TextBox x:Name="textbox2" Margin="6,0"/>
<TextBox x:Name="textbox3" Margin="6"/>
</StackPanel>
</ControlTemplate>
</Window.Resources>
<StackPanel Background="Yellow">
<UserControl x:Name="uc" Template="{StaticResource cTmp}" Margin="5"/>
<Button Content="FindName" Click="Button_Click"/>
</StackPanel>
</Window>
事件
private void Button_Click(object sender, RoutedEventArgs e)
{
//Template.FindName
TextBox tb= uc.Template.FindName("textbox1", this.uc) as TextBox;
tb.Text = "textbox1";
StackPanel sp = tb.Parent as StackPanel;
(sp.Children[1] as TextBox).Text = "textbox2";
(sp.Children[2] as TextBox).Text = "textbox3";
}
如果获得与业务相关的数据,直接访问底层(WPF采用数据驱动UI逻辑)Content
效果:
[csharp] view plain copy
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Skill { get; set; }
public bool HasJob { get; set; }
}
XAML
<Window x:Class="AutomaticConfigurationAPP.Window6"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AutomaticConfigurationAPP"
Title="Window6" Height="300" Width="300">
<Window.Resources>
<local:Student x:Key="stu" Id="1" Name="姓名" Skill="wpf" HasJob="True"/>
<DataTemplate x:Key="stuDT">
<Border BorderBrush="Orange" BorderThickness="2" CornerRadius="5">
<StackPanel>
<TextBlock Text="{Binding Id}" Margin="5"/>
<TextBlock x:Name="textblockname" Text="{Binding Name}" Margin="5"/>
<TextBlock Text="{Binding Skill}" Margin="5"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ContentPresenter x:Name="cp"
Content="{StaticResource stu}"
ContentTemplate="{StaticResource stuDT}"
Margin="5"/>
<!--Content="{StaticResource 内容数据源}" ContentTemplate="{StaticResource 内容模板}"-->
<Button Content="Find" Margin="5,0" Click="Button_Click"/>
</StackPanel>
</Window>
C#
//内容模板查找控件
TextBlock tb= this.cp.ContentTemplate.FindName("textblockname", this.cp) as TextBlock; //CP就是一个contentpresenter
MessageBox.Show(tb.Text);
//直接使用底层数据
Student stu = this.cp.Content as Student;
MessageBox.Show(stu.Name);
XAML
<Window x:Class="AutomaticConfigurationAPP.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:local="clr-namespace:AutomaticConfigurationAPP"
Title="Window2" Height="300" Width="300">
<Window.Resources>
<c:ArrayList x:Key="stuList">
<local:Student Id="1" Name="a" Skill="wpf" HasJob="True"/>
<local:Student Id="2" Name="b" Skill="MVC" HasJob="True"/>
<local:Student Id="3" Name="c" Skill="c#" HasJob="True"/>
</c:ArrayList>
<DataTemplate x:Key="nameDT">
<TextBox x:Name="textboxname" Text="{Binding Name}" GotFocus="textboxname_GotFocus"/>
</DataTemplate>
<DataTemplate x:Key="skillDT">
<TextBox x:Name="textboxskill" Text="{Binding Skill}"/>
</DataTemplate>
<DataTemplate x:Key="hasjobDT">
<CheckBox x:Name="checkboxJob" IsChecked="{Binding HasJob}"/>
</DataTemplate>
</Window.Resources>
<Grid Margin="5">
<ListView x:Name="listviewStudent" ItemsSource="{StaticResource stuList}">
<ListView.View>
<!--ListView的View属性是GridView-->
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}"/>
<!--CellTemplate是TextBox-->
<GridViewColumn Header="姓名" CellTemplate="{StaticResource nameDT}"/>
<GridViewColumn Header="技能" CellTemplate="{StaticResource skillDT}"/>
<GridViewColumn Header="已工作" CellTemplate="{StaticResource hasjobDT}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
c#
private void textboxname_GotFocus(object sender, RoutedEventArgs e)
{
//访问业务逻辑数据
TextBox tb = e.OriginalSource as TextBox;//获得事件的源头(TextBox)
//沿UI元素树上溯到DataTemplate的目标控件(ContentPresenter),并获取它内容,它内容一定是个Student
ContentPresenter cp = tb.TemplatedParent as ContentPresenter;
Student stu = cp.Content as Student;//一行
//MessageBox.Show(stu.HasJob.ToString());
this.listviewStudent.SelectedItem = stu;
//访问界面逻辑数据
//查找包含的ListViewItem
ListViewItem lvi = this.listviewStudent.ItemContainerGenerator.ContainerFromItem(stu) as ListViewItem;
CheckBox chb = this.FindVisualChild<CheckBox>(lvi);
MessageBox.Show(chb.Name);
}
private ChildType FindVisualChild<ChildType>(DependencyObject obj)
where ChildType:DependencyObject
{
//可视化对象包含的子集个数
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
//返回指定父可视对象中位于指定集合索引位置的子可视对象
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is ChildType)
{
return child as ChildType;
}
else
{
ChildType childofChild = FindVisualChild<ChildType>(child);
if (childofChild != null)
return childofChild;
}
}
return null;
}
ControlTemplate 对象: 访问其目标控件 Template . [b]FindName就能拿到。[/b]
DataTemplate 对象: 直接使用低层数据(如果想获得控件长度、宽度 [b]Template . FindName)。[/b]
1、获得[b]ControlTemplate 中的控件。[/b]
效果:<Window x:Class="AutomaticConfigurationAPP.Window5"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window5" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="cTmp">
<StackPanel Background="Orange">
<TextBox x:Name="textbox1" Margin="6"/>
<TextBox x:Name="textbox2" Margin="6,0"/>
<TextBox x:Name="textbox3" Margin="6"/>
</StackPanel>
</ControlTemplate>
</Window.Resources>
<StackPanel Background="Yellow">
<UserControl x:Name="uc" Template="{StaticResource cTmp}" Margin="5"/>
<Button Content="FindName" Click="Button_Click"/>
</StackPanel>
</Window>
事件
private void Button_Click(object sender, RoutedEventArgs e)
{
//Template.FindName
TextBox tb= uc.Template.FindName("textbox1", this.uc) as TextBox;
tb.Text = "textbox1";
StackPanel sp = tb.Parent as StackPanel;
(sp.Children[1] as TextBox).Text = "textbox2";
(sp.Children[2] as TextBox).Text = "textbox3";
}
2、获得DataTemplate 中的控件。
如果获得与用户界面相关的数据(比如控件的宽度、高度)ContentTemplate.FindName("")。如果获得与业务相关的数据,直接访问底层(WPF采用数据驱动UI逻辑)Content
效果:
[csharp] view plain copy
public class Student
{
public int Id { get; set; }
public string Name { get; set; }
public string Skill { get; set; }
public bool HasJob { get; set; }
}
XAML
<Window x:Class="AutomaticConfigurationAPP.Window6"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:AutomaticConfigurationAPP"
Title="Window6" Height="300" Width="300">
<Window.Resources>
<local:Student x:Key="stu" Id="1" Name="姓名" Skill="wpf" HasJob="True"/>
<DataTemplate x:Key="stuDT">
<Border BorderBrush="Orange" BorderThickness="2" CornerRadius="5">
<StackPanel>
<TextBlock Text="{Binding Id}" Margin="5"/>
<TextBlock x:Name="textblockname" Text="{Binding Name}" Margin="5"/>
<TextBlock Text="{Binding Skill}" Margin="5"/>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
<StackPanel>
<ContentPresenter x:Name="cp"
Content="{StaticResource stu}"
ContentTemplate="{StaticResource stuDT}"
Margin="5"/>
<!--Content="{StaticResource 内容数据源}" ContentTemplate="{StaticResource 内容模板}"-->
<Button Content="Find" Margin="5,0" Click="Button_Click"/>
</StackPanel>
</Window>
C#
//内容模板查找控件
TextBlock tb= this.cp.ContentTemplate.FindName("textblockname", this.cp) as TextBlock; //CP就是一个contentpresenter
MessageBox.Show(tb.Text);
//直接使用底层数据
Student stu = this.cp.Content as Student;
MessageBox.Show(stu.Name);
实例:访问业务逻辑数据、访问界面逻辑数据
界面:XAML
<Window x:Class="AutomaticConfigurationAPP.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:System.Collections;assembly=mscorlib"
xmlns:local="clr-namespace:AutomaticConfigurationAPP"
Title="Window2" Height="300" Width="300">
<Window.Resources>
<c:ArrayList x:Key="stuList">
<local:Student Id="1" Name="a" Skill="wpf" HasJob="True"/>
<local:Student Id="2" Name="b" Skill="MVC" HasJob="True"/>
<local:Student Id="3" Name="c" Skill="c#" HasJob="True"/>
</c:ArrayList>
<DataTemplate x:Key="nameDT">
<TextBox x:Name="textboxname" Text="{Binding Name}" GotFocus="textboxname_GotFocus"/>
</DataTemplate>
<DataTemplate x:Key="skillDT">
<TextBox x:Name="textboxskill" Text="{Binding Skill}"/>
</DataTemplate>
<DataTemplate x:Key="hasjobDT">
<CheckBox x:Name="checkboxJob" IsChecked="{Binding HasJob}"/>
</DataTemplate>
</Window.Resources>
<Grid Margin="5">
<ListView x:Name="listviewStudent" ItemsSource="{StaticResource stuList}">
<ListView.View>
<!--ListView的View属性是GridView-->
<GridView>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding Id}"/>
<!--CellTemplate是TextBox-->
<GridViewColumn Header="姓名" CellTemplate="{StaticResource nameDT}"/>
<GridViewColumn Header="技能" CellTemplate="{StaticResource skillDT}"/>
<GridViewColumn Header="已工作" CellTemplate="{StaticResource hasjobDT}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
c#
private void textboxname_GotFocus(object sender, RoutedEventArgs e)
{
//访问业务逻辑数据
TextBox tb = e.OriginalSource as TextBox;//获得事件的源头(TextBox)
//沿UI元素树上溯到DataTemplate的目标控件(ContentPresenter),并获取它内容,它内容一定是个Student
ContentPresenter cp = tb.TemplatedParent as ContentPresenter;
Student stu = cp.Content as Student;//一行
//MessageBox.Show(stu.HasJob.ToString());
this.listviewStudent.SelectedItem = stu;
//访问界面逻辑数据
//查找包含的ListViewItem
ListViewItem lvi = this.listviewStudent.ItemContainerGenerator.ContainerFromItem(stu) as ListViewItem;
CheckBox chb = this.FindVisualChild<CheckBox>(lvi);
MessageBox.Show(chb.Name);
}
private ChildType FindVisualChild<ChildType>(DependencyObject obj)
where ChildType:DependencyObject
{
//可视化对象包含的子集个数
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
{
//返回指定父可视对象中位于指定集合索引位置的子可视对象
DependencyObject child = VisualTreeHelper.GetChild(obj, i);
if (child != null && child is ChildType)
{
return child as ChildType;
}
else
{
ChildType childofChild = FindVisualChild<ChildType>(child);
if (childofChild != null)
return childofChild;
}
}
return null;
}
相关文章推荐
- Repeater获取HeaderTemplate和FooterTemplate模板中的控件
- 在WPF中获取DataGridTemplateColumn模板定义的内容控件
- 在WPF中获取DataGridTemplateColumn模板定义的内容控件
- wpf 模板内控件在后台CS文件里面获取属性值
- Silverlight实用窍门系列:66.Silverlight的数据模板DataTemplate(二)获取数据模板控件
- Silverlight实用窍门系列:66.Silverlight的数据模板DataTemplate(二)获取数据模板控件
- 浅析Page.LoadTemplate("模板")方法动态获取绑定模板后,通过FindControl获取服务端控件的方法。
- 如何获取gridview中模板列中控件的值?
- Xamarin XAML语言教程构建ControlTemplate控件模板 (二)
- NET2005中如何获取DataGrid模板里TextBox的值(<ItemTemplate>)
- Delphi中如何获取TDateTimePicker控件的属性值
- silverlight之How To:访问控件模板里的控件
- 从外部的js文件中获取ASPX页面的服务端控件ClientID
- WPF DataGridTemplateColumn 获取内部控件
- ASP.NET Repeater 头模板(HeaderTemplate)和FooterTemplate模板中查找控件
- [ASP.NET]DataList中获取FooterTemplate中控件的研究
- 从外部的js文件中获取ASPX页面的控件ClientID
- winform用户控件的子控件具有外部访问权限
- 为什么Jquery有时候根据模板中控件的Id但是获取不到该控件的对象
- 从外部的js文件中获取ASPX页面的控件ClientID