zoukankan      html  css  js  c++  java
  • WPF 基础

    1. 关系

    • 凡是 Template,最后都得作用到 控件 上,这个控件就是 Template 的目标控件(也称模板化控件);
    • DataTemplate 一般是落实在一个 ContentPresenter 对象上,而 ContentPresenter 类只有 ContentTemplate 属性、没有 Template 属性,这可以说明它的专门用途是承载由 DataTemplate 生成的一组控件;
    • ControlTemplate 生成的控件树其树根是 ControlTemplate 的目标控件,此目标控件的 Template 属性值是这个 ControlTemplate 实例;
    • DataTemplate 生成的控件树其树根是一个 ContentPresenter 控件,此目标控件的 ContentTemplate 属性值是这个 DataTemplate 实例;
    • 因为 ContentPresenter 控件是 ContentTemplate 控件树上的一个结点,所以 DataTemplate 控件树是 ContentTemplate 控件树的一颗子树;
    • 如果由 Template 生成的控件使用了 TemplateBinding 获取属性值,则 TemplateBinding 的数据源就是应用了这个模板的目标控件;
    • 如果把数据对象赋值给 ContentPresenter 的 DataContext 属性,由 DataTemplate 生成的控件自然会找到这个数据对象并把它当做自己的数据源。

    简而言之:

    typeof(Control.Template) = ControlTemplate
    typeof(Control.ContentTemplate) = DateTemplate ∈ ContentPresenter
    ContentPresenter.DateContext => Controls(∈ Datemplate).DataContext

    2. 应用

    2.1 ControlTemplate 的应用

    1. 设置 key,由需要的控件调用;
    2. 不设置 key,统一运用到某个类型的控件。
    <Style TargetType="{x:Type TextBox">
        <Setter Property="Template">
            <Setter.Value>
                <ContentPresenter TargetType="{x:Type TextBox}">
                    ...
                </ContentPresenter>
            </Setter.Value>
        </Setter>
    </Style>
    
    <TextBox />
    <TextBox />
    <!--如果不需要这个样式,就另行设置 Style 的属性值-->
    <TextBox Style="{x:Null}"/>
    

    2.2 DataTemplate 的应用

    同理于 ControlTemplate。

    2.2.1 DataTemplate 实例

    <DataTemplate DataType="{x:Type xx}">
        <Grid>
            ...
        </Grid>
    </DataTemplate>
    
    xmlns:sys="clr-namespace:System.Collections;assembly=mscorlib"
        
    <DataTemplate DataType="{x:Type local:Unit}">
        <Grid>
            ...
        </Grid>
    </DataTemplate>
    
    <sys:ArrayList x:key="unitList">
        <local:Unit Year="2010" Price="100"/>
        <local:Unit Year="2011" Price="110"/>
        <local:Unit Year="2012" Price="120"/>
    </sys:ArrayList>
    
    <ListBox ItemsSource="{StaticResource unitList}" />
    
    public Class Unit
    { 
        public string Year { get; set; }
        public string Price { get; set; }
    }
    

    虽然没有为 ListBox 指定 ItemTemplate,当 DataTemplate 会自动加载到所有 Unit 类型对象上。

    2.2.2 把 XML 数据结点当作目标对象

    DataTemplate 具有直接把 XML 数据结点当做目标对象的功能;

    • XML 数据中元素名作为 DataType
    • 可使用 XPath 访问元素的 子结点
    • 可使用 XPath 访问元素的 Attribute
    • XPath 可以在 XmlDataProvider 标签中或 Binding 中定义
    2.2.2.1 只用 XML 的一层
    <Window.Resources>
        <XmlDataProvider x:Key="ds" XPath="Units/Unit">
            <x:XData>
                <Units xmlns="">
                    <Unit Year="2001" Price="110"/>
                    <Unit Year="2002" Price="120"/>
                    <Unit Year="2003" Price="130"/>
                    <Unit Year="2004" Price="140"/>
                </Units>
            </x:XData>
        </XmlDataProvider>
    
        <DataTemplate DataType="Unit">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <Grid>
                        <Rectangle Fill="LightSalmon" Width="{Binding XPath=@Price}"/>
                        <TextBlock Text="{Binding XPath=@Year}"/>
                    </Grid>
                    <TextBlock Text="{Binding XPath=@Price}"/>
                </StackPanel>
            </Grid>
        </DataTemplate>      
    </Window.Resources>
    
    <StackPanel>
        <ListBox ItemsSource="{Binding Source={StaticResource ds}}" />
        <ComboBox ItemsSource="{Binding Source={StaticResource ds}}" Margin="0 10 0 0" />
    </StackPanel>
    
    <Window.Resources>
        <XmlDataProvider x:Key="ds">
        ..
        
    <ListBox ItemsSource="{Binding Source={StaticResource ds}, XPath=/Units/Unit}" />
    
    2.2.2.2 支持 HeaderedItemsControl 的 DataTemplate:HierarchicalDataTemplate

    HierarchicalDataTemplate 表示支持 System.Windows.Controls.HeaderedItemsControl 的 System.Windows.DataTemplate,例如 System.Windows.Controls.TreeViewItem 或 System.Windows.Controls.MenuItem。

    <Window.Resources>
        <XmlDataProvider x:Key="ds" XPath="Data/Units">
            <x:XData>
                <Data xmlns="">
                    <Units Name="单元组A">
                        <Unit Name="A 组 A 房">
                            <Student Name="AA1" Age="16"></Student>
                            <Student Name="AA2" Age="17"></Student>
                            <Student Name="AA3" Age="18"></Student>
                        </Unit>
                        <Unit Name="A 组 B 房">
                            <Student Name="AB1" Age="26"></Student>
                            <Student Name="AB2" Age="27"></Student>
                            <Student Name="AB3" Age="28"></Student>
                        </Unit>
                    </Units>
                    <Units Name="单元组B">
                        <Unit Name="B 组 A 房">
                            <Student Name="BA1" Age="16"></Student>
                            <Student Name="BA2" Age="17"></Student>
                            <Student Name="BA3" Age="18"></Student>
                        </Unit>
                        <Unit Name="B 组 B 房">
                            <Student Name="BB1" Age="26"></Student>
                            <Student Name="BB2" Age="27"></Student>
                            <Student Name="BB3" Age="28"></Student>
                        </Unit>
                    </Units>
                </Data>
            </x:XData>
        </XmlDataProvider>
        <HierarchicalDataTemplate DataType="Units" ItemsSource="{Binding XPath=Unit}">
            <TextBlock Text="{Binding XPath=@Name}"/>
        </HierarchicalDataTemplate>
    
        <HierarchicalDataTemplate DataType="Unit" ItemsSource="{Binding XPath=Student}">
            <RadioButton Content="{Binding XPath=@Name}" GroupName="gn"/>
        </HierarchicalDataTemplate>
    
        <HierarchicalDataTemplate DataType="Student" ItemsSource="{Binding XPath=bu}">
            <CheckBox>
                <StackPanel Orientation="Horizontal">
                    <TextBlock Text="{Binding XPath=@Name}" Margin="0 0 10 0"/>
                    <TextBlock Text="{Binding XPath=@Age}"/> 
                </StackPanel>
            </CheckBox>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <StackPanel>
        <ListBox ItemsSource="{Binding Source={StaticResource ds}}" />
        <TreeView ItemsSource="{Binding Source={StaticResource ds}}"></TreeView>
    </StackPanel>
    

    ListBox 只展示了两行 单元组A、单元组B;
    TreeView 展示了树形结果,展示了 xml 的所有结点

    <!--Data.xml-->
    <?xml version="1.0" encoding="utf-8" ?>
    <Data xmlns="">
        <Operation Name="文件" Gesture="F">
            <Operation Name="新建" Gesture="N">
                <Operation Name="项目" Gesture="Control + P"/>
                <Operation Name="网站" Gesture="Control + W"/>
                <Operation Name="文档" Gesture="Control + D"/>
            </Operation>
            <Operation Name="保存" Gesture="S"/>
            <Operation Name="打印" Gesture="P"/>
            <Operation Name="退出" Gesture="X"/>
        </Operation>
        <Operation Name="编辑" Gesture="E">
            <Operation Name="拷贝" Gesture="Control + C"/>
            <Operation Name="剪切" Gesture="Control + X"/>
            <Operation Name="粘贴" Gesture="Control + V"/>
        </Operation>
    </Data>
    
    ...
    
    <Window.Resources>
        <XmlDataProvider x:Key="ds" Source="Data.xml" XPath="Data/Operation"/>
            
        <HierarchicalDataTemplate DataType="Operation" ItemsSource="{Binding XPath=Operation}">
            <StackPanel Orientation="Horizontal">
                <TextBlock Text="{Binding XPath=@Name}" Margin="10,0"/>
                <TextBlock Text="{Binding XPath=@Gesture}"/>
            </StackPanel>
        </HierarchicalDataTemplate>
    </Window.Resources>
    <StackPanel MenuItem.Click="StackPanel_Click">
        <Menu ItemsSource="{Binding Source={StaticResource ds}}"/>
    </StackPanel>
    
    private void StackPanel_Click(object sender, RoutedEventArgs e)
    {
        MenuItem mi = e.OriginalSource as MenuItem;
    
        System.Xml.XmlElement xe = mi.Header as System.Xml.XmlElement;
    
        string name = xe.Attributes["Name"].Value;
        string gesture = xe.Attributes["Gesture"].Value;
    
    }
    

    总结:
    1)e.Source 是 Menu,e.OriginalSource 是 MenuItem;
    2)HierarchicalDataTemplate 的作用目标不是 MenuItem 的内容,而是 MenuItem 的 Header;
    3)可以监听 MenuItem 的单击事件,然后从路由参数的 OriginalSource 取出 MenuItem,取出 MenuItem 就能取出属性名为 Header 的值,从而取到某个特性的值;
    4)搭配工厂模式,根据点击的 MenuItem 执行对应的操作。

  • 相关阅读:
    使用Oracle ODP.NET 11g的.NET程序发布方法
    Client使用c#和odp.net连接server oracle
    打造百度网盘备份利器:自动备份Linux VPS文件和多线程下载百度网盘资源
    安装软件:/lib/ld-linux.so.2: bad ELF interpreter解决
    ArcSDE数据库连接(直连、服务连)与GT_Geometry存
    AE的Annotation学习摘记
    Samba简单配置--匿名用户共享资料可读可写的实现
    Sublime Text 2 使用心得
    ArcGIS Server启动服务报:ERROR: Unable to start Xvfb on any port in the range 6600
    [DataContract] 和[DataMember]
  • 原文地址:https://www.cnblogs.com/MichaelLoveSna/p/14450825.html
Copyright © 2011-2022 走看看