wpf中在style的template寻找ControlTemplate和DataTemplate的控件
一、WPF中的两棵树
WPF中每个控件的Template都是由ControlTemplate构成,ControlTemplate包含了构成该控件的各种子控件,这些子控件就构成了VisualTree;而在我们可见的界面,所有搭建出整个程序UI的控件构成了LoginTree。VisualTree和LoginTree相互独立,互相不可访问,每中树都有各自的方法来查找自己的子控件。
二、寻找ControlTemplate中的控件
首先,我们在资源中新建一个包含三个TextBox的ControlTemplate,把它赋值给一个UserControl对象;然后我们再在程序界面添加一个TextBox,在资源中引用之前把TextBox改成圆角风格的Style:
1 <Window x:Class="_11_221.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525"> 5 <Window.Resources> 6 <ControlTemplate x:Key="cTmp"> 7 <StackPanel Background="Orange"> 8 <TextBox x:Name="textBox1" Margin="6"/> 9 <TextBox x:Name="textBox2" Margin="6,0"/> 10 <TextBox x:Name="textBox3" Margin="6"/> 11 </StackPanel> 12 </ControlTemplate> 13 <Style BasedOn="{x:Null}" TargetType="{x:Type TextBox}" x:Key="tbstyle"> 14 <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> 15 <Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/> 16 <Setter Property="BorderThickness" Value="1"/> 17 <Setter Property="Padding" Value="1"/> 18 <Setter Property="AllowDrop" Value="true"/> 19 <Setter Property="FocusVisualStyle" Value="{x:Null}"/> 20 <Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/> 21 <Setter Property="Stylus.IsFlicksEnabled" Value="False"/> 22 <Setter Property="Template"> 23 <Setter.Value> 24 <ControlTemplate TargetType="{x:Type TextBox}"> 25 <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="true" 26 CornerRadius="10"> 27 <TextBlock x:Name="textblck1" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> 28 </Border> 29 <ControlTemplate.Triggers> 30 <Trigger Property="IsEnabled" Value="false"> 31 <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/> 32 <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> 33 </Trigger> 34 </ControlTemplate.Triggers> 35 </ControlTemplate> 36 </Setter.Value> 37 </Setter> 38 </Style> 39 40 </Window.Resources> 41 <Grid> 42 <StackPanel Background="Yellow"> 43 <UserControl x:Name="uc" Template="{StaticResource cTmp}" Margin="5"/> 44 <TextBox x:Name="tb" Style="{StaticResource tbstyle}"/> 45 <Button Content="find" Width="120" Height="30" Click="Button_Click"/> 46 </StackPanel> 47 </Grid> 48 </Window>
我们实现的效果是,点击按钮,分别从UserControl和TextBox中找到构成他们的ControlTemplate,然后找到子控件并进行相关操作:
后台代码:
1 private void Button_Click(object sender, RoutedEventArgs e) 2 { 3 TextBox t = this.uc.Template.FindName("textBox1", this.uc) as TextBox; 4 t.Text = "hello"; 5 StackPanel sp = t.Parent as StackPanel; 6 (sp.Children[1] as TextBox).Text = "hello controltemplate"; 7 (sp.Children[2] as TextBox).Text = "find it"; 8 9 TextBlock tbl = this.tb.Template.FindName("textblck1", this.tb) as TextBlock; 10 tbl.Text = "in textbox"; 11 }
ControlTemplate和DateTemplate都属于Template,都可以给Template进行赋值,Template中提供了一个叫做FindName的接口,可以用来寻找模板中的控件。
三、寻找DataTemplate中的控件
首先,先定义一个用于使用DataTemplate的类Student:
1 public class Student 2 { 3 public int Id { get; set; } 4 public string Name { get; set; } 5 public string Skill { get; set; } 6 public bool HasJob { get; set; } 7 }
XMAL代码如下:
1 <Window x:Class="_11_222.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:local="clr-namespace:_11_222" 5 Title="MainWindow" Height="350" Width="525"> 6 <Window.Resources> 7 <local:Student x:Key="stu" Id="1" Name="Hyman" Skill="Linux" HasJob="True"/> 8 <DataTemplate x:Key="stuDT"> 9 <StackPanel Orientation="Horizontal"> 10 <TextBox Name="textbox1" Text="{Binding Id}"/> 11 <TextBox Name="textbox2" Text="{Binding Name}"/> 12 <TextBox Name="textbox3" Text="{Binding Skill}"/> 13 </StackPanel> 14 </DataTemplate> 15 </Window.Resources> 16 <Grid> 17 <StackPanel> 18 <ContentPresenter x:Name="cp" Content="{StaticResource stu}" ContentTemplate="{StaticResource stuDT}" /> 19 <Button x:Name="button" Width="120" Height="30" Click="button_Click" Content="find"/> 20 </StackPanel> 21 </Grid> 22 </Window>
实现find按钮的处理函数,将找到的TextBox中的内容用MessageBox弹出:
1 private void button_Click(object sender, RoutedEventArgs e) 2 { 3 TextBox tb = this.cp.ContentTemplate.FindName("textbox2", this.cp) as TextBox; 4 MessageBox.Show(tb.Text); 5 }
界面效果如下:
转自:http://blog.csdn.net/hyman_c/article/details/52020310