WPF--模板選擇
阿新 • • 發佈:2017-11-13
設備名 width 全局 clas nbsp select 一個 ech return
典型的,把模板關聯到一塊特定的數據上,不過通常希望動態的確定使用哪個模板---既可以基於一個屬性值,也可以是一個全局狀態。當真正需要大規模替換模板時,也可以使用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>
效果如下:
這個是自己畫了對勾和叉叉然後當模板了。
WPF--模板選擇