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

    效果如下:

    360软件小助手截图20130728130801

    好了完成了,本实例除了可以学怎样动态进行模板选择,哪还将学会怎样使用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>
    效果如下:
    360软件小助手截图20130728131741
    这个是自己画了对勾和叉叉然后当模板了。
  • 相关阅读:
    iOS网络编程--NSConnection的同步连接与异步连接
    NSThread基础使用
    多线程基础
    《软件工程》总结
    作业4(结对编程项目--四则运算)
    PSP记录个人项目耗时情况
    作业3
    作业二 流行的源程序版本管理软件和项目管理软件各自的优点缺点
    作业2
    作业
  • 原文地址:https://www.cnblogs.com/sjqq/p/7827050.html
Copyright © 2020-2023  润新知