日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > asp.net >内容正文

asp.net

WPF模板(二)应用

發布時間:2025/7/25 asp.net 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 WPF模板(二)应用 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
原文:WPF模板(二)應用

? ? ? ? ? 本次內容來源于電子書,和上一篇一樣。

在WPF中有三大模板ControlTemplate,ItemsPanelTemplate,DataTemplate.其中ControlTemplate和ItemsPanelTemplate是控件模板,DataTemplate是數據模板,他們都派生自FrameworkTemplate抽象類。

1、ControlTemplate

ControlTemplate:控件模板主要有兩個重要屬性:VisualTree內容屬性和Triggers觸發器。所謂VisualTree(視覺樹),就是呈現我們所畫的控件。Triggers可以對我們的視覺樹上的元素進行一些變化。一般用于單內容控件。

畫一個按鈕模板來舉例說明:

<Style TargetType="Button"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="Button"> <Grid> <Ellipse Width="100" Height="100"> <Ellipse.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="blue"/> <GradientStop Offset="1" Color="LightBlue"/> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> <Ellipse Width="80" Height="80"> <Ellipse.Fill> <LinearGradientBrush StartPoint="0,0" EndPoint="0,1"> <GradientStop Offset="0" Color="White"/> <GradientStop Offset="1" Color="Transparent"/> </LinearGradientBrush> </Ellipse.Fill> </Ellipse> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style>

<Button Content="Hello WPF"/>

結果:

ControlTemplate之子 ContentControl和ContentPresenter

我們在ControlTemplate中畫了兩個橢圓,應用于所有的Button按鈕,但我們Button中有Content屬性(內容為Hello WPF),卻沒有顯示出來。因為這里用ControlTemplate重寫了Button的樣式,所以我們也要在ControlTemplate中增加ContentControl。通過ContentControl中的Content來綁定父容器的Content屬性。

<Style TargetType="Button"><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="Button"><Grid><Ellipse Width="100" Height="100"><Ellipse.Fill><LinearGradientBrush StartPoint="0,0" EndPoint="0,1"><GradientStop Offset="0" Color="blue"/><GradientStop Offset="1" Color="LightBlue"/></LinearGradientBrush></Ellipse.Fill></Ellipse><Ellipse Width="80" Height="80"><Ellipse.Fill><LinearGradientBrush StartPoint="0,0" EndPoint="0,1"><GradientStop Offset="0" Color="White"/><GradientStop Offset="1" Color="Transparent"/></LinearGradientBrush></Ellipse.Fill></Ellipse><ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/></Grid></ControlTemplate></Setter.Value></Setter></Style>

?

這下內容出來了

我們來看一下,ContentControl繼承于Control的,用MSDN的話是:表示包含單項內容的控件、ContentControl 可以包含任何類型的公共語言運行庫對象。如下ContentControl類圖。

為了提高性能,我們可以用一個ControlPresenter來代替ContentControl,效果還是一樣,那他們有什么區別呢?

來看下ControlPresenter這個類,它繼承于FreameworkElement,如下圖:

ControlPresenter 通常叫做內容占位符。所以我們可以看到

<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>來代替<ContentControl VerticalAlignment="Center" HorizontalAlignment="Center"?Content="{TemplateBinding Content}"/>?。這里少了Content綁定父容器,因為ControlPresenter有個隱式的Content="{TemplateBinding Content}",也就是你可以寫也可以不寫它。

從他們的基類可以看出,ContentControl比ContentPresenter大多了。其實ControlPresenter是一個原始的構建塊,而ContentControl是一個帶控件模板的成熟控件(里面包含ControlPresenter)。

所以我們一般用ControlPresenter。

ControlTemplate的VisualTree我們講過了,下面看下他的trigger如何運用。

我們在原來的代碼中增加

<ControlTemplate.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter TargetName="ellipse1" Property="Fill" Value="Red"/> </Trigger> </ControlTemplate.Triggers>

當我們把鼠標移上去的時候就會變成如下圖所示:

發揮我們的想象力,我們可以根據ControlTemplate做更多的特效。如下

<Style TargetType="CheckBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="CheckBox"> <DockPanel> <ContentPresenter DockPanel.Dock="Left" VerticalAlignment="Center" /> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="30"/> <ColumnDefinition Width="30"/> </Grid.ColumnDefinitions> <Rectangle Grid.Column="0" Grid.ColumnSpan="2" Fill="Gray"/> <TextBlock x:Name="txtBox" Foreground="White" /> </Grid> </DockPanel> <ControlTemplate.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter TargetName="txtBox" Property="Grid.Column" Value="1"/> <Setter TargetName="txtBox" Property="Text" Value="On"/> <Setter TargetName="txtBox" Property="Background" Value="LightBlue"/> </Trigger> <Trigger Property="IsChecked" Value="{x:Null}"> <Setter TargetName="txtBox" Property="Grid.Column" Value="0"/> </Trigger> <Trigger Property="IsChecked" Value="false"> <Setter TargetName="txtBox" Property="Grid.Column" Value="0"/> <Setter TargetName="txtBox" Property="Text" Value="OFF"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Grid> <CheckBox Width="100" Height="30" Content="Click Me"/> </Grid>

效果圖:點擊之前點擊之后

2、ItemsPanelTemplate

ItemsPanelTemplate在MSDN的解釋是:ItemsPanelTemplate 指定用于項的布局的面板。?GroupStyle?具有一個類型為 ItemsPanelTemplate 的?Panel屬性。?ItemsControl?類型具有一個類型為ItemsPanelTemplate 的?ItemsPanel?屬性。

我們先講ItemTemplate。它一般用在多個內容控件的模板。比如ListBox。

如下看ListBox應用ItemTemplate:

在xaml中

<Style TargetType="ListBox"><Setter Property="ItemTemplate"><Setter.Value><DataTemplate><Image Source="{Binding UriSource}" Width="100" Height="100"/> </DataTemplate> </Setter.Value> </Setter> </Style>

? <ListBox x:Name="listBox" />

在后臺代碼我們給它一些圖片來填充這個ListBox.

public partial class ListBoxUserControl : UserControl{public ListBoxUserControl(){InitializeComponent();listBox.ItemsSource = LoadImages();}public List<BitmapImage> LoadImages(){List<BitmapImage> bitmapImages=new List<BitmapImage>();DirectoryInfo directoryInfo = new DirectoryInfo(@"E:\WPFDEMO\ControlTest\ControlTest\Images");foreach (var item in directoryInfo.GetFiles("*.jpg")){Uri uri=new Uri(item.FullName);bitmapImages.Add(new BitmapImage(uri));}return bitmapImages;}}

每一張圖片就是一個Item。

我們如果想讓圖片以橫向顯示。一開始我以為用StackPanel的Orientation=”Horiziontal”,發現犯了個錯誤。這樣設置是現在把Items中某一個item中的內容水平顯示啊。這時就要用到ItemsPanelTemplate這個模板了。我們在ListBox的樣式中增加如下紅色區域的代碼:

<Style TargetType="ListBox"><Setter Property="ItemTemplate"><Setter.Value><DataTemplate><StackPanel Orientation="Horizontal"><Image Source="{Binding UriSource}" Width="100" Height="100"/> <TextBlock Text="qq" Background="Red"/> </StackPanel> </DataTemplate> </Setter.Value> </Setter>

<Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <StackPanel /> </ItemsPanelTemplate> </Setter.Value> </Setter>

</Style>


這里我在DataTemplate中加了StackPanel 為了說明加在這里的效果只是區分:Items整體橫向和Item中內容的區別。

現在我們要想讓布局可以隨著窗體寬度變化,我們只要把ItemsPanelTemplate中的StackPanel 改成WrapPanel,并且設置ListBox的ScrollViewer.HorizontalScrollBarVisibility="Disabled",這樣才可以看到效果。

ControlTemplate之 ItemsPresenter和ContentPresenter

我們先構造一個TreeView

xaml中:

在開始加個Loaded="UserControl_Loaded"

<Grid> <TreeView x:Name="treeview" /> </Grid>

后臺代碼中:

public class Node{private IList<Node> _childNodes;private string _name;public Node(){}public Node(string name){_name = name;}public string Name{get { return _name; }set { _name = value; }}public IList<Node> ChildNodes{get{if (_childNodes==null)_childNodes=new List<Node>();return _childNodes;}}}public partial class TreeViewUserControl : UserControl{public TreeViewUserControl(){InitializeComponent();}private void UserControl_Loaded(object sender, RoutedEventArgs e){treeview.PreviewKeyDown += (o,a) => { a.Handled = true; };PopulateTreeView();}void PopulateTreeView(){Node rootNode=new Node("GrandFather");for (int i = 0; i < 2; i++){Node child=new Node("Father");rootNode.ChildNodes.Add(child);for (int j = 0; j < 3; j++){Node child2=new Node("Son");child.ChildNodes.Add(child2);}}Node dummy=new Node();dummy.ChildNodes.Add(rootNode);treeview.ItemsSource = dummy.ChildNodes;}}

?

沒有任何樣式的TreeView

下面我們如何運用ItemsPresenter和ContentPresenter來添加樣式。來實現下面這幅圖的效果


在TreeView中ItemsPresenter和ContentPresenter是什么關系:ContentPresenter是用來顯示TreeView中Item的內容 。ItemsPresenter是用來顯示它的子項(Item的子項,也就是說child’s Items)。

<Style TargetType="TreeViewItem"><Style.Resources><LinearGradientBrush x:Key="ItemAreaBrush" StartPoint="0,0.5" EndPoint="0.5,1"><GradientStop Offset="0" Color="#66000000"/><GradientStop Offset="1" Color="#22000000"/></LinearGradientBrush><LinearGradientBrush x:Key="SelectedItemAreaBrush" StartPoint="0.5, 0" EndPoint="0.5, 1"><GradientStop Color="Orange" Offset="0" /><GradientStop Color="OrangeRed" Offset="1" /></LinearGradientBrush><LinearGradientBrush x:Key="ItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1"><GradientStop Color="LightGray" Offset="0" /><GradientStop Color="Gray" Offset="1" /></LinearGradientBrush><LinearGradientBrush x:Key="SelectedItemBorderBrush" StartPoint="0.5, 0" EndPoint="0.5, 1"><GradientStop Color="Yellow" Offset="0" /><GradientStop Color="Black" Offset="1" /></LinearGradientBrush><DropShadowBitmapEffect x:Key="DropShadowEffect"/></Style.Resources><Setter Property="Template"><Setter.Value><ControlTemplate TargetType="TreeViewItem"><Grid Margin="2"><Grid.RowDefinitions><RowDefinition Height="auto"/><RowDefinition Height="*"/></Grid.RowDefinitions><Border x:Name="border" Background="{StaticResource ResourceKey=ItemAreaBrush}" BorderBrush="{StaticResource ItemBorderBrush}" BorderThickness="1" CornerRadius="8" Padding="6"><ContentPresenter ContentSource="Header" VerticalAlignment="Center" HorizontalAlignment="Center"/></Border><ItemsPresenter Grid.Row="1"/></Grid><ControlTemplate.Triggers><Trigger Property="IsSelected" Value="true"><Setter TargetName="border" Property="Panel.Background" Value="{StaticResource SelectedItemAreaBrush}"/></Trigger></ControlTemplate.Triggers></ControlTemplate></Setter.Value></Setter><Setter Property="ItemsPanel"><Setter.Value><ItemsPanelTemplate><StackPanel Orientation="Horizontal" HorizontalAlignment="Center" IsItemsHost="True"/></ItemsPanelTemplate></Setter.Value></Setter></Style>

看紅色代碼的部分,這里ContentPresenter顯示了父容器的Header的內容,比如GrandFather,Father,Son.而ItemsPresenter則是否讓他顯示其子元素。比如GrandFather的子元素為Father,沒有設置<ItemsPresenter Grid.Row="1"/>?的話。子元素Father是不會顯示的。

這里為了突出層次化,運用了ItemsPanelTemplate。最后我們在資源里引用這個樣式。

<UserControl.Resources><ResourceDictionary><ResourceDictionary.MergedDictionaries><ResourceDictionary Source="/Controls/TreeViewItemStyle.xaml"/></ResourceDictionary.MergedDictionaries><HierarchicalDataTemplate DataType="{x:Type controls:Node}" ItemsSource="{Binding ChildNodes}"><TextBlock Text="{Binding Name}"/></HierarchicalDataTemplate></ResourceDictionary></UserControl.Resources>

?

3、DataTemplate和HierarchicalDataTemplate

DataTemplate就是顯示綁定數據對象的模板。
HierarchicalDataTemplate繼承于DataTemplate,它專門對TreeViewItem?或?MenuItem的一些數據對象的綁定。

總結

以上是生活随笔為你收集整理的WPF模板(二)应用的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。