WPF 基础 - 在模板中找元素
1. 在 ControlTemplate 中寻找元素
<Window.Resources>
<ControlTemplate x:Key="cTmp">
<StackPanel>
<StackPanel.Resources>
<Style TargetType="TextBlock">
<Setter Property="Margin" Value="6"/>
</Style>
</StackPanel.Resources>
<TextBlock x:Name="tb1" Text="tb1"/>
<TextBlock x:Name="tb2" Text="tb2"/>
<TextBlock x:Name="tb3" Text="tb3"/>
</StackPanel>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<UserControl x:Name="uc" Template="{StaticResource cTmp}" />
<Button Click="Button_Click" Content="FindName" Width="90" Height="25"/>
</StackPanel>
private void Button_Click(object sender, RoutedEventArgs e)
{
TextBlock tb = this.uc.Template.FindName("tb1", this.uc) as TextBlock;
tb.Text = "I Find the first one";
StackPanel sp = tb.Parent as StackPanel;
(sp.Children[1] as TextBlock).Text = "I am the second one";
(sp.Children[2] as TextBlock).Text = "I am the third one";
}
this.xx.Template.FindName((string)elementName, this.xx) as typeof(elementType);
2. 在 DateTemplate 中寻找元素
类似于 ControlTemplate,可以使用
this.xx.ContentTemplate.FindName(string(elementName), this.xx) as typeof(elementType) 寻找元素;
但我们一般是为了获取控件的长度、宽度,而不是为了获取内容的某个属性;
要获取内容的某个属性,不必绕到表层控件上来。
<Window.Resources>
<coll:ArrayList x:Key="stuList">
<local:Student Id="1" Name="Mao1" LoveBasketball="True"></local:Student>
<local:Student Id="2" Name="Mao2" LoveBasketball="False"></local:Student>
<local:Student Id="3" Name="Mao3" LoveBasketball="True"></local:Student>
<local:Student Id="4" Name="Mao4" LoveBasketball="False"></local:Student>
<local:Student Id="5" Name="Mao5" LoveBasketball="True"></local:Student>
<local:Student Id="6" Name="Mao6" LoveBasketball="False"></local:Student>
</coll:ArrayList>
<DataTemplate x:Key="dtId">
<TextBlock Text="{Binding Id}"/>
</DataTemplate>
<DataTemplate x:Key="dtName">
<TextBox x:Name="textBoxName" Text="{Binding Name}" GotFocus="TextBoxName_GotFocus" />
</DataTemplate>
<DataTemplate x:Key="dtLoveBasketball">
<CheckBox x:Name="checkBoxLove" IsChecked="{Binding LoveBasketball}" IsEnabled="False"/>
</DataTemplate>
</Window.Resources>
<StackPanel MenuItem.Click="StackPanel_Click">
<ListView x:Name="list_stu" ItemsSource="{StaticResource stuList}">
<ListView.View>
<GridView x:Name="ddr">
<GridViewColumn Header="Id" CellTemplate="{Binding Source={StaticResource dtId}}"></GridViewColumn>
<GridViewColumn x:Name="dd" Header="Name" CellTemplate="{Binding Source={StaticResource dtName}}"></GridViewColumn>
<GridViewColumn Header="LoveBasketball" CellTemplate="{Binding Source={StaticResource dtLoveBasketball}}"></GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
private void TextBoxName_GotFocus(object sender, RoutedEventArgs e)
{
TextBox tb = e.OriginalSource as TextBox; // 获取事件发起的源头
ContentPresenter cp = tb.TemplatedParent as ContentPresenter; // 获取模板目标
Student stu = cp.Content as Student; // 获取业务逻辑数据,[DataTemplate 落实在 ContentPresenter 上,ContentPresenter 是 ControlTemplate 的一个结点]
this.list_stu.SelectedItem = stu; // 设置 ListView 的选中项
ListViewItem lvi = this.list_stu.ItemContainerGenerator.ContainerFromItem(stu) as ListViewItem;
CheckBox cb = this.FindVisualChild<CheckBox>(lvi);
Console.WriteLine(cb.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;
}
- 当使用 GridView 作为 ListView 的 View 属性值,如果某一列使用 TextBox 作为 CellTemplate,那么即使这列中的 TextBox 被鼠标单击并获得焦点,ListView 也不会把此项作为自己的 SelectedItem;
- 在 ListBox 中 ItemTemplate 下的 TextBox 也是如此;
- 因此 TextBoxName_GotFocus 先获取事件的最初源头,然后沿着 UI 元素树上溯到 DataTemplate 的目标控件(ContentPresenter)并获取它的内容,必是一个 Student 实例;
- 使用 ItemsControl 的 ItemContainerGenerator.ContainerFromItem 方法获得包装这指定条目数据的容器 ListViewItem;
- ListViewItem 的 Content 也是 Student 实例。
前面 ListViewItem 的可视化树
Border1-->ListViewItem
Border2-->Border1
Grid-->Border2
Rectangle-->Grid
GridViewRowPresenter-->Grid
ContentPresenter1-->GridViewRowPresenter
TextBlock-->ContentPresenter1
ContentPresenter2-->GridViewRowPresenter
TextBox-->ContentPresenter2
ContentPresenter3-->GridViewRowPresenter
CheckBox-->ContentPresenter3
Border3-->TextBox
ScrollViewer-->Border3
Grid2-->ScrollViewer
Rectangle2-->Grid2
ScrollContentPresenter-->Grid2
TextBoxView-->ScrollContentPresenter
TextBoxLineDrawingVisual-->TextBoxView
AdornerLayer-->ScrollContentPresenter
ScrollBar-->Grid2
ScrollBar2-->Grid2
<StackPanel MenuItem.Click="StackPanel_Click">
<StackPanel.Resources>
<DataTemplate x:Key="it">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Id}"/>
<TextBox x:Name="textBoxName" Text="{Binding Name}" GotFocus="TextBoxName_GotFocus" Margin="15 0"/>
<CheckBox x:Name="checkBoxLove" IsChecked="{Binding LoveBasketball}"/>
</StackPanel>
</DataTemplate>
<Style TargetType="ListBoxItem">
<Setter Property="ContentTemplate" Value="{StaticResource it}"/>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Id}" Value="3"/>
<Condition Binding="{Binding Name}" Value="Mao3"/>
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Red"></Setter>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</StackPanel.Resources>
<ListBox x:Name="list_stu2" ItemsSource="{StaticResource stuList}" >
</ListBox>
</StackPanel>
WPF 基础 - 在模板中找元素的更多相关文章
- WPF 寻找数据模板中的元素
<Window x:Class="Wpf180706.Window11" xmlns="http://schemas.microsoft.com/wi ...
- WPF 寻找控件模板中的元素
<Window x:Class="Wpf180706.Window10" xmlns="http://schemas.microsoft.com/wi ...
- Vue基础-在模板中使用过滤器
Vue 测试版本:Vue.js v2.5.13 官网给了过滤器的两种使用方式: 1.你可以在一个组件的选项中定义本地的过滤器: 结合实例,我给两个代码: <div id="app&qu ...
- 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中的元素
[源码下载] 背水一战 Windows 10 (76) - 控件(控件基类): Control - 基础知识, 焦点相关, 运行时获取 ControlTemplate 和 DataTemplate 中 ...
- selenium中的元素操作之三大切换(二)
一.窗口切换 使用方法: 1.获取到打开的所有的窗口,句柄handles all_handles = driver.window_handles print(all_handles) 2.获取当前的窗 ...
- WPF关于控件 父级控件,子级控件,控件模板中的控件,等之间的相互访问
原文:WPF关于控件 父级控件,子级控件,控件模板中的控件,等之间的相互访问 1,在菜单中访问 弹出菜单的控件 var mi = sender as MenuItem;//菜单条目 MenuItem ...
- WPF ListBoxItem模板中添加CheckBox选中问题
原文:WPF ListBoxItem模板中添加CheckBox选中问题 是这样的,需要一个ListBox来展示照片,并添加一个选中的CheckBox.这就需要对ListBox的ItemTemplate ...
- Vue基础系列(三)——Vue模板中的数据绑定语法
写在前面的话: 文章是个人学习过程中的总结,为方便以后回头在学习. 文章中会参考官方文档和其他的一些文章,示例均为亲自编写和实践,若有写的不对的地方欢迎大家和我一起交流. VUE基础系列目录 < ...
- 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵
题目描述: 一个N*M的矩阵,找出这个矩阵中所有元素的和不小于K的面积最小的子矩阵(矩阵中元素个数为矩阵面积) 输入: 每个案例第一行三个正整数N,M<=100,表示矩阵大小,和一个整数K 接下 ...
随机推荐
- CS224--1:语言模型和词向量
参考: https://www.cnblogs.com/pinard/p/7243513.html https://blog.csdn.net/cindy_1102/article/details/8 ...
- c++ cin 读入txt的问题
源程序 #include <iostream> using namespace std; struct Stack { int tos; int stackarray[1000]; }; ...
- Caffe入门:对于抽象概念的图解分析
Caffe的几个重要文件 用了这么久Caffe都没好好写过一篇新手入门的博客,最近应实验室小师妹要求,打算写一篇简单.快熟入门的科普文. 利用Caffe进行深度神经网络训练第一步需要搞懂几个重要文件: ...
- HDU 4049 Tourism Planning(状压DP)题解
题意:m个城市,n个人,让这n个人按固定顺序走遍m个城市.每个城市有一个单人票价pi.每个人在每个城市能获得vij的价值.如果多个人在同一城市,那么会额外获得价值,给出一张n * n价值表,额外价值为 ...
- 慕课网站 & MOOC website
慕课网站 & MOOC website MOOC, massive open online course Mooc for everyone ! 国家精品课程 & 在线学习平台 慕课平 ...
- vue & child component & props
vue & child component & props vue pass data to child component https://vuejs.org/v2/guide/co ...
- SVG 2 & SVG & getPointAtLength & getPathSegAtLength
SVG 2 & SVG & getPointAtLength & getPathSegAtLength getPointAtLength SVG 1.x https://dev ...
- 比起USDT,我为什么建议你选择USDN
2018年1月16日,USDT(泰达币)进入了很多人的视野.因为在这一天,在全球价值排名前50的加密货币中,包括比特币.莱特币以及以太坊在内的大多数的数字虚拟加密货币都遭遇了价格大幅下跌,只有泰达币价 ...
- 快速读懂 HTTP/3 协议
在 深入浅出:HTTP/2 一文中详细介绍了 HTTP/2 新的特性,比如头部压缩.二进制分帧.虚拟的"流"与多路复用,性能方面比 HTTP/1 有了很大的提升.与所有性能优化过程 ...
- 五分钟快速上手MyBatis
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL.存储过程以及高级映射. 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作. 可以通过简单的 XML 或注解来配置和映射,Ja ...