WPF--模板选择
典型的,把模板关联到一块特定的数据上,不过通常希望动态的确定使用哪个模板---既可以基于一个属性值,也可以是一个全局状态。当真正需要大规模替换模板时,也可以使用DataTemplateSelector。
DataTemplateSelector提供了一个单一的方法----SelectTemplate,以允许通过执行任何逻辑来决定使用哪个模板。可以在被包含的元素中查找模板,并返回一些硬编码的模板,甚至动态的为每个条目创建模板。
首先,创建一个继承自DataTemplateSelector的类,并完成一些在几个模板中进行旋转的逻辑。在这个例子中,将找到XmlElement的LocalName,并从容器中获取具有该名称的资源,代码如下:
public class LocalNameTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate (object item,DependencyObject container)
{
XmlElement data = item as XmlElement;
if (data != null)
{
return ((FrameworkElement)container).FindResource(data.LocalName) as DataTemplate;
}
return null;
}
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
为了初始化所有的模板,将构建三个模板:用于书籍的棕色矩形,用于CD的银色圆形以及用于DVD的蓝色圆形。由于模板选择器将查找XmlElement的本地名称,所以需要为每个模板设置X:Key,代码如下:
<DataTemplate x:Key="Book" DataType="{x:Type sx:XmlElement}">
<StackPanel Orientation="Horizontal">
<Rectangle Margin="2" Width="14" Height="14" Fill="Brown"/>
<TextBlock VerticalAlignment="Center" Text="{Binding XPath=@Title}"></TextBlock>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="CD" DataType="{x:Type sx:XmlElement}">
<StackPanel Orientation="Horizontal">
<Ellipse Margin="2" Width="14" Height="14" Fill="Silver"/>
<TextBlock VerticalAlignment="Center" Text="{Binding XPath=@Title}"></TextBlock>
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="DVD" DataType="{x:Type sx:XmlElement}">
<StackPanel Orientation="Horizontal">
<Ellipse Margin="2" Width="14" Height="14" Fill="Blue"/>
<TextBlock VerticalAlignment="Center" Text="{Binding XPath=@Title}"></TextBlock>
</StackPanel>
</DataTemplate>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
余下的就是把模板选择器和ListBox进行关联,而不是设置静态模板,代码如下:
<ListBox ItemsSource="{Binding XPath=/Media/*}">
<ListBox.ItemTemplateSelector>
<l:LocalNameTemplateSelector xmlns:l="clr-namespace:WpfProgressBarDemo"/>
</ListBox.ItemTemplateSelector>
</ListBox>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
前台完整代码如下:
<Window x:Class="WpfProgressBarDemo.DataTemplateSelectorDemo"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sx="clr-namespace:System.Xml;assembly=System.Xml" Title="DataTemplateSelector" Height="300" Width="300" DataContext="{DynamicResource dataSource}"
> <Window.Resources>
<!--数据源-->
<XmlDataProvider x:Key="dataSource">
<x:XData>
<Media xmlns="">
<Book Author="Aretch" Title="WCF全面解析"/>
<Book Author="ByVoid" Title="Node.js开发指南"/>
<Book Author="Rogers Cardenhead" Title="21天学通Java"/>
<CD Title="没有CD了"/>
<DVD Title="《十面埋伏》"/>
</Media>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="Book" DataType="{x:Type sx:XmlElement}">
<StackPanel Orientation="Horizontal">
<Rectangle Margin="2" Width="14" Height="14" Fill="Brown"/>
<TextBlock VerticalAlignment="Center" Text="{Binding XPath=@Title}"></TextBlock>
</StackPanel>
</DataTemplate> <DataTemplate x:Key="CD" DataType="{x:Type sx:XmlElement}">
<StackPanel Orientation="Horizontal">
<Ellipse Margin="2" Width="14" Height="14" Fill="Silver"/>
<TextBlock VerticalAlignment="Center" Text="{Binding XPath=@Title}"></TextBlock>
</StackPanel>
</DataTemplate> <DataTemplate x:Key="DVD" DataType="{x:Type sx:XmlElement}">
<StackPanel Orientation="Horizontal">
<Ellipse Margin="2" Width="14" Height="14" Fill="Blue"/>
<TextBlock VerticalAlignment="Center" Text="{Binding XPath=@Title}"></TextBlock>
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding XPath=/Media/*}">
<ListBox.ItemTemplateSelector>
<l:LocalNameTemplateSelector xmlns:l="clr-namespace:WpfProgressBarDemo"/>
</ListBox.ItemTemplateSelector>
</ListBox>
</Grid>
</Window>
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
效果如下:

好了完成了,本实例除了可以学怎样动态进行模板选择,哪还将学会怎样使用XML数据绑定。另外为了使读者能更好的理解,现提供另一个我项目中的例子供大家参考
后台:
public class LocalNameTemplateSelector : DataTemplateSelector
{
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
if (item != null && item is DeviceCheckInfo)
{
DeviceCheckInfo device = item as DeviceCheckInfo; Window2 win = new Window2();
if (device.CheckResult)
return win.FindResource("dui") as DataTemplate;
else
return win.FindResource("cuo") as DataTemplate;
}
return null;
}
} public class DeviceCheckInfo
{
//设备名称
public string Name { get; set; }
//检测内容
public string CheckContent { get; set; }
//检测结果
public bool CheckResult { get; set; }
}
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
Xaml部分:
<Window x:Class="WpfProgressBarDemo.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfProgressBarDemo"
Title="Window2" Height="433" Width="500" Loaded="Window_Loaded">
<Window.Resources>
<local:IShowTrueOrFalse x:Key="convetToImage"></local:IShowTrueOrFalse> <Style TargetType="TextBlock" >
<Setter Property="HorizontalAlignment" Value="Center"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Margin" Value="30"/>
<Setter Property="FontSize" Value="20"/>
</Style> <DataTemplate x:Key="dui" DataType="{x:Type local:DeviceCheckInfo}" >
<StackPanel Orientation="Horizontal" CheckBox.Checked="StackPanel_Checked">
<TextBlock Text="{Binding Path=Name}" Margin="10" VerticalAlignment="Center" FontSize="20"/>
<TextBlock Text="{Binding Path=CheckContent}" Margin="10" VerticalAlignment="Center" FontSize="20"/>
<Path x:Name="dui" Data="M43,5 L20,40 20,40 0,20 6,15 18,26 37,7 43,5 z" Fill="Green" Margin="5" Stretch="Fill"/>
<CheckBox Name="checkbox" Checked="checkbox_Checked"/>
</StackPanel>
</DataTemplate> <DataTemplate x:Key="cuo" DataType="{x:Type local:DeviceCheckInfo}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Path=Name}" Margin="10" VerticalAlignment="Center" FontSize="20"/>
<TextBlock Text="{Binding Path=CheckContent}" Margin="10" VerticalAlignment="Center" FontSize="20"/> <Path Margin="5" Data="M50,25 L25,50 M25,25 50,50" Fill="#FFF4F4F5" Height="40" Stretch="Fill" Stroke="Red" Width="40" StrokeThickness="8"/>
<CheckBox Name="checkbox" Checked="checkbox_Checked"/>
</StackPanel>
</DataTemplate>
<local:LocalNameTemplateSelector x:Key="myDataTemplateSelector"/>
</Window.Resources> <Grid>
<ListBox Name="lbtest" ItemTemplateSelector="{StaticResource myDataTemplateSelector}" SelectionChanged="lbtest_SelectionChanged" /> </Grid>
</Window>
效果如下:
这个是自己画了对勾和叉叉然后当模板了。
.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }
WPF--模板选择的更多相关文章
- WPF范围选择控件(RangeSelector)
原文:WPF范围选择控件(RangeSelector) 版权声明:本文为博主原创文章,转载请注明作者和出处 https://blog.csdn.net/ZZZWWWPPP11199988899/art ...
- WPF快速入门系列(7)——深入解析WPF模板
一.引言 模板从字面意思理解是“具有一定规格的样板".在现实生活中,砖块都是方方正正的,那是因为制作砖块的模板是方方正正的,如果我们使模板为圆形的话,则制作出来的砖块就是圆形的,此时我们并不 ...
- WPF 模板绑定父级控件内容
WPF 模板绑定父级控件内容 <Style TargetType="Button" x:Key="btn"> <Setter Property ...
- WPF自定义选择年月控件详解
本文实例为大家分享了WPF自定义选择年月控件的具体代码,供大家参考,具体内容如下 封装了一个选择年月的控件,XAML代码: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ...
- WPF源代码分析系列一:剖析WPF模板机制的内部实现(一)
众所周知,在WPF框架中,Visual类是可以提供渲染(render)支持的最顶层的类,所有可视化元素(包括UIElement.FrameworkElment.Control等)都直接或间接继承自Vi ...
- WPF动态模板选择的两种实现
前言 .net开发工作了六年,看了大量的博客,现在想开始自己写博客,这是我的第一篇博客,试试水,就从自己最常使用的WPF开始. 今天我来给大家分享可用户动态选择控件模板的两种实现方式:DataTrig ...
- WPF中模板选择和DataContext的一些使用
如图样: View结构 MainView(MainViewModel)|---Guide1View(Guide1ViewModel)|---Guide2View(Guide2ViewModel) |- ...
- WPF模板(一)详细介绍
本次随笔来源于电子书,人家的讲解很好,我就不画蛇添足了. 图形用户界面应用程序较之控制台界面应用程序最大的好处就是界面友好.数据显示直观.CUI程序中数据只能以文本的形式线性显示,GUI程序则允许数据 ...
- wpf 模板选择器DataTemplateSelector及动态绑定使用教程
其实也说不上算是教程了,只是把自己学习的代码拿出来分享一下,同时方便以后遇到类似问题的时候翻一下.MSDN里如是说:通常,如果有多个 DataTemplate 可用于同一类型的对象,并且您希望根据每个 ...
- WPF模板
WPF的中模板有三种:ControlTemplate.ItemsPanelTemplate.DataTemplate,他们继承抽象类FrameworkTemplate,下面是它们的继承关系: Wind ...
随机推荐
- 取得cxgrid的表格的值,仔细看下面的代码
procedure TfrmMain.cxGridDBTableView_List_PSSJCustomDrawCell(Sender: TcxCustomGridTableView; ACanvas ...
- Android-Java-等待唤醒机制原理
儿时的游戏:(等待 与 唤醒) 有一群小朋友一起玩一个游戏,这个游戏可能大家都玩过,大家一起划拳,划拳输得最惨的那个小朋友去抓人(这个小朋友取名为 CPU),被抓的很多人取名为线程,有很多线程,如果其 ...
- 附加题:将四则运算源代码上传到Github账户上
1.创建仓库用于存储管理本地文件 2.远程添加github上的Blog仓库. 3.获取github中Blog仓库的地址. 4.在Add Remote窗口中填写名字.Location. 5.将本地文件通 ...
- .net图表之ECharts随笔01-最简单的使用步骤
找了几种绘制图表的办法,后面选定了ECharts.下载链接如下,好像不同的ECharts有不同的用法,要下对. https://gitee.com/Tuky/SomeWebFrame/tree/mas ...
- OpenvSwitch端口镜像
OVS上实现端口镜像的基本流程如下: 创建 mirror ,在 mirror 中指定镜像数据源及镜像目的地 将创建的 mirror 应用到 bridge 中 镜像数据源可以通过下面几个选项来指定: s ...
- iOS-项目开发1-图片浏览器
FFBrowserImageViewController 自定义的图片浏览器:支持图片双击放大,单击取消,拖动取消. 重点: 1:在iOS11之后再布局是要将UIScrollViewContentIn ...
- [vuejs] vue2.0-layer-mobile移动端弹层
vue2.0-layer-mobile移动端弹层 本次组件升级支持slot内容分发功能,实现高定制内容风格的弹层 安装方法 npm install vue2-layer-mobile -S 初始化 i ...
- flask_mysql入库
mysql 的入库和MongoDB的有一点点的区别 不过都很重要,都必须要掌握的技能, 现在我来演示一下mysql入库的过程: 首先 我们要导包,这是必不可少的一部分,都不用我说了吧 #导报 imp ...
- Spring框架的演变
什么是Spring 如果想要解释Spring,那么最难的部分就是对其进行分类.通常情况下,Spring被描述为构建Java应用程序的轻量级框架,但这种描述带来了两个有趣的观点. 首先,与许多其他框架( ...
- matlab中元胞数组的创建与内容读取
一.创建元胞数组 1.用cell命令创建规格为2*2的空元胞 >> a=cell(2,2) a = [] [] [] [] 2.用大括号"{}"创建元胞数组并赋值 &g ...
