《15天玩转WPF》—— Data / Control 模板的使用(二)

上一篇关于模板的文章:
《深入浅出WPF》—— Data / Control 模板的使用(一)

为 Template 设置其应用目标有两种方法:

  1. 一种是逐个设置控件的 Template / ContentTemplate 等属性,不想应用则不设置(上一文用
  2. 一种是 整体应用,即 把 Template应用在某个控件或数据上

文章目录


ControlTemplate的应用

把 ControlTemplate 应用在所有目标上需要借助 Style 来实现,但 Style 不能标记 x:Key

例如下面的代码:

<Window x:Class="WpfApp31.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"        
        Title="MainWindow" Height="150" Width="230">

	<Window.Resources>
        <Style TargetType="{x:Type TextBox}">

// *************************************** //
            <Setter Property="Template">
                <Setter.Value>
                	<ControlTemplate TargetType="{x:Type TextBox}">
                        <Border x:Name="border" CornerRadius="20" BorderBrush="{TemplateBinding BorderBrush}"
                         	BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" 
                         		SnapsToDevicePixels="True">
                        </Border>
                    </ControlTemplate>
	        </Setter.Value>
           </Setter>
// *************************************** //
           <Setter Property="Margin" Value="5"/>
           <Setter Property="BorderBrush" Value="Black"/>
           <Setter Property="Height" Value="25"/>
           <Setter Property="Background" Value="LightBlue"/>
	</Style>
    	</Window.Resources>
    	
    <StackPanel>
        <TextBox/>
        <TextBox/>
        <TextBox Style="{x:Null}" Background="Black"/>	   
    </StackPanel>
    
</Window>

核心部分我已经用 // *** // 标记 . . .

我们发现,控件模块就是修改了一些风格而已,并且作用于指定的类型
Style 没有 x:Key标记,默认为应用到所有由 x:Type指定的控件上,如果不需要则把 Style设置 {x:null}

效果如下:

在这里插入图片描述

其中,前两个 TextBox为默认风格,第三个 Style为 null . . .


DataTemplate的应用

把 DataTemplate 应用在某个数据类型上的方法是设置 DataTemplate 的 Data属性,并且把 DataTemplate 作为资源时也不能带有 x:Key标记。

很多时候数据是以 XML形式存储的,因为这样做很方便DataTemplate 很智能,具有直接把 XML数据结点当作目标对象的功能 —— XML 数据中的元素名(标签名)可以作为 DataType元素的子结点 和 Attribute 可以使用 XPath来访问

我们需要完成上一文中类似的数据柱形图:参考开头的链接

下面的代码使用 XmlDataProvider 作为数据源(XPath 必需指出一组结点:Units/Unit ):

<Window x:Class="WpfApp33.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataTemplate" SizeToContent="WidthAndHeight">

    <Window.Resources>

// *************************************************//
        <DataTemplate DataType="Unit">
            <Grid>
                <StackPanel Orientation="Horizontal">
                    <Grid>
                        <Rectangle Stroke="Yellow" Fill="Orange" 
                            Width="{Binding XPath=@Price}"/>
                        <TextBlock Text="{Binding XPath=@Year}"/>
                    </Grid>
		    <TextBlock Text="{Binding XPath=@Price}" Margin="5,0"/>
                </StackPanel>
            </Grid>
        </DataTemplate>

// *************************************************//

       <XmlDataProvider x:Key="ds" XPath="Units/Unit">
            <x:XData>
                <Units xmlns="">	
		    <Unit Year ="2001" Price="100"/>
                    <Unit Year ="2002" Price="120"/>
                    <Unit Year ="2003" Price="140"/>
                    <Unit Year ="2004" Price="150"/>
		    <Unit Year ="2005" Price="130"/>
                    <Unit Year ="2006" Price="160"/>
                </Units>
            </x:XData>

        </XmlDataProvider>

// *************************************************//

    </Window.Resources>

    <StackPanel>
        <ListBox ItemsSource="{Binding Source={StaticResource ds}}"/>
        <ComboBox ItemsSource="{Binding Source={StaticResource ds}}" Margin="5"/>
    </StackPanel>
</Window>

代码分为三部分:

  1. 定义DataTemplate,指定 DataType, @表示引入xml结点的特性 . . .
  2. XmlDataProvider,提供数据
  3. 引用数据,数据被默认添加模板

结果图如下:

在这里插入图片描述


HierarchicalDataTemplate的应用

XML最大的优势是可以方便地表示带有层级的数据,比如:

  • 年级 --> 班级 --> 小组
  • 主菜单 --> 次级菜单 --> 三级菜单

同时,WPF准备了 TreeViewMenuItem 控件用来显示 层级数据 。能够帮助层级控件显示层级数据的模板是 HierarchicalDataTemplate

下面我们将举两个例子来测试一下它们 . . .


TreeView使用

使用 TreeView显示多层级、不同类型数据。因为数据类型不同,所以我们需要为每种数据设计一个模板,这就可以将每种数据类型表示独有的外观。

为了方便,我们将数据直接向上面一样,定义在XAML代码中,日常项目中,我们可以写在单独的 xml文件中. . .

<Window x:Class="WpfApp34.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataTemplate" SizeToContent="WidthAndHeight">
        <Window.Resources>

//********************************************//
        <XmlDataProvider x:Key="ds" XPath="Data/Grade">
            <x:XData>
                <Data xmlns="">
                <Grade Name ="一年级">
                        <Class Name="甲班">
                            <Group Name="A 组"/>
                            <Group Name="B 组"/>
                            <Group Name="C 组"/>
                        </Class>

			<Class Name="乙班">
                            <Group Name="A 组"/>
                            <Group Name="B 组"/>
                            <Group Name="C 组"/>
                        </Class>
		</Grade>

                <Grade Name ="二年级">
                        <Class Name="甲班">
                            <Group Name="A 组"/>
                            <Group Name="B 组"/>
                            <Group Name="C 组"/>
                        </Class>
                        
                        <Class Name="乙班">
                            <Group Name="A 组"/>
                            <Group Name="B 组"/>
                            <Group Name="C 组"/>
                        </Class>
               </Grade>
              </Data>
            </x:XData>
        </XmlDataProvider>

//********************************************//

        <HierarchicalDataTemplate DataType="Grade" ItemsSource="{Binding XPath=Class}">
            <TextBlock Text="{Binding XPath=@Name}"/>
        </HierarchicalDataTemplate>

        <HierarchicalDataTemplate DataType="Class" ItemsSource="{Binding XPath=Group}">
            <RadioButton Content="{Binding XPath=@Name}" GroupName="gn"/>
        </HierarchicalDataTemplate>	

        <HierarchicalDataTemplate DataType="Group" ItemsSource="{Binding XPath=Student}">
            <CheckBox Content="{Binding XPath=@Name}"/>
        </HierarchicalDataTemplate>

//********************************************//

</Window.Resources>
 
    <Grid>
        <TreeView Margin="5" ItemsSource="{Binding Source={StaticResource ds}}"/>                    
    </Grid>

</Window>

代码分为三部分:

  1. 使用 XmlDataProvider 定义树形数据,年级 --> 班级 --> 小组
  2. 使用层级模板 HierarchicalDataTemplate,表示显示的数据模样
  3. 使用 TreeView 调用资源数据

效果如下:

在这里插入图片描述


MenuItem使用

下面的例子是同一种数据类型的嵌套结构,我们只需要设计一个 HierarchicalDataTemplate 就可以了,它会产生自动迭代应用的效果

像上面一样,数据仍然放在 XAML中,代码如下:

<Window x:Class="WpfApp35.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="HierarchicalDataTemplate " Height="300" Width="300">

    <Window.Resources>
        <XmlDataProvider x:Key="ds" XPath="Data/Operation">
            <x:XData>
                <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>
            </x:XData>
        </XmlDataProvider>

        <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
        	<Menu x:Name="m" ItemsSource="{Binding Source={StaticResource ds}}"/>
    	</StackPanel>
  
</Window>                         

和上面的 TreeView一样,都是先定义数据,然后使用层级模板修饰数据,最后引用数据 . . .


作者:浪子花梦

  • 8
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值