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 接下 ...
随机推荐
- 【转】Dockerfile
1. 关于docker build docker build可以基于Dockerfile和context打包出一个镜像,其中context是一系列在PATH或URL中指定的位置中的文件(contex ...
- Leetcode(712)-账户合并
给定一个列表 accounts,每个元素 accounts[i] 是一个字符串列表,其中第一个元素 accounts[i][0] 是 名称 (name),其余元素是 emails 表示该帐户的邮箱地址 ...
- JVM学习路线
JVM探究 请你谈谈你对JVM的理解? java8虚拟机和之前的变化更新? 什么是OOM,什么是栈溢出StackOverFlowError?怎么分析? JVM的常用调优参数有哪些? 内存快照如何抓取, ...
- LeetCode 最大收益的分配工作
LeetCode 最大收益的分配工作 工作安排 现在有n位工程师和6项工作(编号为0至5),现在给出每个人能够胜任的工作序号表(用一个字符串表示,比如:045,表示某位工程师能够胜任0号,4号,5号工 ...
- set CSS style in js solutions All In One
set CSS style in js solutions All In One css in js set each style property separately See the Pen se ...
- React Transforming Elements All In One
React Transforming Elements All In One https://reactjs.org/docs/react-api.html#transforming-elements ...
- SwiftUI & MVVM
SwiftUI & MVVM design paradigm / 设计模式 MVVM Model View ViewModel MVVM Architecture 架构 MVC Model V ...
- css3 units & 1 turn
css3 units & 1 turn One full circle is 1turn, 180deg === 0.5turn degrees, gradians, radians, tur ...
- iframe 父子互传消息,父页面滚动,子页面触发父页面高度
https://blog.csdn.net/qq_38366657/article/details/81538145 // 父页面的js<iframe id='TopHeader' src=&q ...
- NGK公链脱颖而出,成为值得期待的项目!
当下2020年是动荡的一年,全世界经济危机汲汲可危,在这个特殊的时刻,有人抱怨说这是最坏的年代,也有人庆幸说这是最好的年代,历史不会重演,但总是惊人的相似,首先带你回顾一下上一次金融危机出现的2008 ...