博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
WPF模板(二)应用
阅读量:5782 次
发布时间:2019-06-18

本文共 5465 字,大约阅读时间需要 18 分钟。

原文:

          本次内容来源于电子书,和上一篇一样。

在WPF中有三大模板ControlTemplate,ItemsPanelTemplate,DataTemplate.其中ControlTemplate和ItemsPanelTemplate是控件模板,DataTemplate是数据模板,他们都派生自FrameworkTemplate抽象类。

1、ControlTemplate

ControlTemplate:控件模板主要有两个重要属性:VisualTree内容属性和Triggers触发器。所谓VisualTree(视觉树),就是呈现我们所画的控件。Triggers可以对我们的视觉树上的元素进行一些变化。一般用于单内容控件。

画一个按钮模板来举例说明:

 
 
 
 
 
 
 
 
 
 
 

<Button Content="Hello WPF"/>

结果:

ControlTemplate之子 ContentControl和ContentPresenter

我们在ControlTemplate中画了两个椭圆,应用于所有的Button按钮,但我们Button中有Content属性(内容为Hello WPF),却没有显示出来。因为这里用ControlTemplate重写了Button的样式,所以我们也要在ControlTemplate中增加ContentControl。通过ContentControl中的Content来绑定父容器的Content属性。

 

这下内容出来了

我们来看一下,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做更多的特效。如下

 
 
 
 
 
 
 
 
 
 
 
 

效果图:点击之前点击之后

2、ItemsPanelTemplate

ItemsPanelTemplate在MSDN的解释是:ItemsPanelTemplate 指定用于项的布局的面板。  具有一个类型为 ItemsPanelTemplate 的 属性。  类型具有一个类型为ItemsPanelTemplate 的  属性。

我们先讲ItemTemplate。它一般用在多个内容控件的模板。比如ListBox。

如下看ListBox应用ItemTemplate:

在xaml中

  <ListBox x:Name="listBox" />

在后台代码我们给它一些图片来填充这个ListBox.

public partial class ListBoxUserControl : UserControl    {        public ListBoxUserControl()        {            InitializeComponent();            listBox.ItemsSource = LoadImages();        }        public List
LoadImages() { List
bitmapImages=new List
(); 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的样式中增加如下红色区域的代码:

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

 

这里我在DataTemplate中加了StackPanel 为了说明加在这里的效果只是区分:Items整体横向和Item中内容的区别。

现在我们要想让布局可以随着窗体宽度变化,我们只要把ItemsPanelTemplate中的StackPanel 改成WrapPanel,并且设置ListBox的ScrollViewer.HorizontalScrollBarVisibility="Disabled",这样才可以看到效果。

ControlTemplate之 ItemsPresenter和ContentPresenter

我们先构造一个TreeView

xaml中:

在开始加个Loaded="UserControl_Loaded"

 

后台代码中:

public class Node    {        private IList
_childNodes; private string _name; public Node() {} public Node(string name) { _name = name; } public string Name { get { return _name; } set { _name = value; } } public IList
ChildNodes { get { if (_childNodes==null) _childNodes=new List
(); 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)。

看红色代码的部分,这里ContentPresenter显示了父容器的Header的内容,比如GrandFather,Father,Son.而ItemsPresenter则是否让他显示其子元素。比如GrandFather的子元素为Father,没有设置<ItemsPresenter Grid.Row="1"/> 的话。子元素Father是不会显示的。

这里为了突出层次化,运用了ItemsPanelTemplate。最后我们在资源里引用这个样式。

 

3、DataTemplate和HierarchicalDataTemplate

DataTemplate就是显示绑定数据对象的模板。

HierarchicalDataTemplate继承于DataTemplate,它专门对 或 的一些数据对象的绑定。

你可能感兴趣的文章
Linux下DHCP服务器配置
查看>>
AndroidStudio中导入SlidingMenu报错解决方案
查看>>
编写高性能的java程序
查看>>
Spring 的配置详解
查看>>
linux已经不存在惊群现象
查看>>
上位机和底层逻辑的解耦
查看>>
关于微信二次分享 配置标题 描述 图片??
查看>>
springcloud使用zookeeper作为config的配置中心
查看>>
校园火灾Focue-2---》洗手间的一套-》电梯
查看>>
bzoj1913
查看>>
L104
查看>>
分镜头脚本
查看>>
链表基本操作的实现(转)
查看>>
邮件发送1
查看>>
[转] libcurl异步方式使用总结(附流程图)
查看>>
编译安装LNMP
查看>>
[转]基于display:table的CSS布局
查看>>
crm 02--->讲师页面及逻辑
查看>>
AS3.0 Bitmap类实现图片3D旋转效果
查看>>
Eigen ,MKL和 matlab 矩阵乘法速度比较
查看>>