《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一樣,都是先定義數據,然後使用層級模板修飾數據,最後引用數據 . . .


作者:浪子花夢

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章