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;
        }
    }

为了初始化所有的模板,将构建三个模板:用于书籍的棕色矩形,用于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>

余下的就是把模板选择器和ListBox进行关联,而不是设置静态模板,代码如下:

 <ListBox ItemsSource="{Binding XPath=/Media/*}">
            <ListBox.ItemTemplateSelector>
                <l:LocalNameTemplateSelector xmlns:l="clr-namespace:WpfProgressBarDemo"/>
            </ListBox.ItemTemplateSelector>
        </ListBox>

前台完整代码如下:

<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>

效果如下:

好了完成了,本实例除了可以学怎样动态进行模板选择,哪还将学会怎样使用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; }
    }

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>

效果如下:

这个是自己画了对勾和叉叉然后当模板了。

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏流媒体

Makefile文件编写

make 的参数有很多, 可以通过 make -h 去查看, 下面只介绍几个我认为比较有用的。

913
来自专栏冷冷

SpringMVC 文件下载时 浏览器不能正确显示另存的文件名

问题:通过打印输出流的方式把文件下载到本地,但是在firebox 中 下载的文件不显示文件的文件名,造成文件不能直接打开,其他浏览器可以直接打开. 原因: 主要...

1865
来自专栏Python、Flask、Django

python中用requests获取API参数

1166
来自专栏Laoqi's Linux运维专列

python3–内置模块

3396
来自专栏程序员互动联盟

【答疑释惑第三十六讲】Windows下如何调试?

疑惑一 Windows窗口程序到底能不能用printf? 很多小伙伴在控制台下写程序时,要打印或者调试很方便,用printf就可以直接打印输出,方便看结果,但是...

2524
来自专栏linux驱动个人学习

VFS四大对象之四-struct file

继上一篇文章: http://yehe.isd.com/column/support-plan/article-edit/93709 四、file结构体 文件对...

3456
来自专栏kalifaの日々

python多线程爬虫爬取顶点小说内容(BeautifulSoup+urllib)

思路 之前写过python爬取起点中文网小说,多线程则是先把爬取的章节链接存到一个列表里,然后写一个函数get_text每次调用这个函数就传一个章节链接,那么就...

3159
来自专栏一个小程序员的成长笔记

HTML5新增属性学习笔记

1、form属性 表单内的从属元素,可以写在表单外部。可以通过指定元素的form属性来声明元素所属表单。form的属性值为表单的id。 1 <form id="...

3189
来自专栏娱乐心理测试

如何在小程序wxml文件中编写js代码

WXS(WeiXin Script)是小程序的一套脚本语言,结合 WXML,可以构建出页面的结构。 wxs可以说就是为了满足能在页面中使用js存在的,在wxm...

463
来自专栏林德熙的博客

win10 UWP 单元测试 WPF 单元测试异步测试

单元测试和重构都是在做完一个小小函数一般就要进行一次,越早做就越好,可以比较早发现问题,这时我们还记得我们写的内容,不过比重构好的是,重构我们经常不知道要叫什么...

432

扫描关注云+社区