DataTemplate 和 ControlTemplate 两个类均派生自 FrameWorkTemplate类。这个类有个 FindName方法 供我们查询内部控件。

 ControlTemplate 对象: 访问其目标控件 Template . FindName就能拿到。

        DataTemplate 对象:     直接使用低层数据(如果想获得控件长度、宽度 Template . FindName)。

 

1、获得ControlTemplate 中的控件。

效果:


 

<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

效果:

  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. }

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;
        }

从外部访问 Template (模板)的控件、获取它的属性值的更多相关文章

  1. 041. asp.net中内容页访问母版页中的控件

    母版页运行机制: 用户通过输入内容也的URL来请求某个页面, 获取该页面后, 读取@Page指令, 如果该指令引用了一个母版页, 则也读取该母版页, 如果也是第一次请求这两个页面, 则母版页和被请求的 ...

  2. 32.10 使用模板更改控件的UI

    32.10  使用模板更改控件的UI 样式是改变WPF控件基本外形的非常好(且非常简单)的方式,它通过为窗口部件的特性设置建立一组默认的值,从而改变WPF控件的基本外形.但是,即使样式允许我们改变各种 ...

  3. WPF数据模板和控件模板

     WPF中有控件模板和数据模板,控件模板可以让我们自定义控件的外观,而数据模板定义了数据的显示方式,也就是数据对象的可视结构,但是这里有一个问题需要考虑,数据是如何显示出来的?虽然数据模板定义了数 ...

  4. InvokeHelper,让跨线程访问/修改主界面控件不再麻烦(转)

    http://bbs.csdn.net/topics/390162519 事实上,本文内容很简单且浅显,所以取消前戏,直接开始.. 源代码:在本文最后 这里是一张动画,演示在多线程(无限循环+Thre ...

  5. 网页中"IE限制网页访问脚本或ActiveX控件"的提示问题的解决方法

    以前从来没有注意过"IE限制网页访问脚本或ActiveX控件"的提示问题,对于这个小细节问题,虽然感觉很别扭,但一直没考虑解决方法,今天才发现该问题可以轻松解决,以下做个小小记录. ...

  6. 设置TextBlock默认样式后,其他控件的Text相关属性设置失效问题

    问题: 定义了默认TextBlock样式后,再次自定义下拉框 or 其他控件 ,当内部含有TextBlock时,设置控件的字体相关样式无效,系统始终使用TextBlock设置默认样式 解决方案: 为相 ...

  7. WPF设置控件获取键盘焦点时的样式FocusVisualStyle

    控件获取焦点除了用鼠标外,可以通过键盘来获取,比如Tab键或者方向键等,需要设置控件获取键盘焦点时的样式,可以通过设置FrameworkElemnt.FocusVisualStyle属性, 因为几乎所 ...

  8. CheckBoxList控件获取多选择,需要遍历

    CheckBoxList控件获取多选择,需要遍历,环境:vs2008 在页面上添加CheckBoxList控件,输入项值 a,b,c,d.然后添加按钮 Button2确定,如何获取CheckBoxLi ...

  9. 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件增加了 PlaceholderText 属性

    [源码下载] 重新想象 Windows 8.1 Store Apps (77) - 控件增强: 文本类控件的增强, 部分控件增加了 Header 属性和 HeaderTemplate 属性, 部分控件 ...

随机推荐

  1. 11、Pickle序列化

    概念:   常用语法:DUMP:把现在内存中的对象状态装到硬盘文件上 常用语法:LOAD:把磁盘文件中的对象导入到内存中 小练习: 字典中存账号信息,用pickle dump到文件中,并load进行修 ...

  2. CMD一键获取cpu信息

    windows + R 输入cmd打开CMD 输入wmic cpu get Name 获取cpu名称-即物理cpu数 cpu get NumberOfCores获取cpu核心数 cpu get Num ...

  3. 接入WebSocket记录 + 一些个人经验

    闲扯 WebSocket 以前没用过,之前写过一篇博客是基于原生socket的(查看)比较复杂,慎入.今天另外一个APP需要接websocket了,然后便找到了facebook的 SocketRock ...

  4. elasticsearch中的filter与aggs

    今天在ES上做了一个聚合,先过滤一个嵌套对象,再对另一个域做聚合,但是过滤似乎没有起作用 { "size":0, "filter":{ "nested ...

  5. js 上传图片进行回显

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  6. C#写的一个视频转换解码器

    C#写的一个视频转换解码器 using System; using System.Collections.Generic; using System.Linq; using System.Text; ...

  7. 爪哇国新游记之二十二----排序判断重复时间复杂度为2n的位图法

    import java.util.ArrayList; import java.util.List; /** * 位图法 * 用于整型数组判重复,得到无重复列表 * */ public class B ...

  8. MPTCP 源码分析(四) 发送和接收数据

    简述:      MPTCP在发送数据方面和TCP的区别是可以从多条路径中选择一条 路径来发送数据.MPTCP在接收数据方面与TCP的区别是子路径对无序包 进行重排后,MPTCP的mpcb需要多所有子 ...

  9. iOS学习笔记之蓝牙(有关蓝牙设备mac地址处理) 2

    1.创建中心设备,并设置代理 一般情况下,手机是中心设备,蓝牙设备是外围设备. self.centralManager = [[CBCentralManager alloc] initWithDele ...

  10. mod_tile编译出错 -std=c++11 or -std=gnu++11

    make[1]: 正在进入文件夹 /home/wml/src/mod_tile-master' depbase=echo src/gen_tile.o | sed 's|[^/]*$|.deps/&a ...