• 从外部访问 Template (模板)的控件、获取它的属性值


    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

    效果:

    [csharp] view plain copy
     
    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;
            }

  • 相关阅读:
    判断鼠标点击在div外时,更改背景图片
    CSS--border边框颜色渐变
    实验一:Java开发环境的熟悉
    实验楼第四次试验报告
    实验楼第三次试验报告
    实验楼第二次试验报告
    实验楼第一次试验报告
    c++程序设计中的函数重载
    C++中,new/delete和malloc/free的区别
    继承和多态二:虚析构函数
  • 原文地址:https://www.cnblogs.com/sjqq/p/8379599.html
Copyright © 2020-2023  润新知