现在我正在使用具有三种不同数据模板,三种视图模型和一个itemtemplate选择器的自定义项控件。
一切正常,但我正在寻求改进此代码。以下是三个数据模板:
<DataTemplate x:Key="RefreshDevicesDataTemplate">
<Grid Margin="5,0">
<myApp:myAppButton Name="RefreshButton" Command="{Binding Command}" ToolTip="Refresh Devices" Style="{StaticResource TransparentStyle}">
<Rectangle x:Name="RefreshRectangle" Width="20" Height="20" ToolTip="{Binding ToolTip}" Fill="{Binding IconBrush}" Opacity="1" Margin="0,0,0,6"/>
</myApp:myAppButton>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsWaiting}" Value="True">
<Setter Property="Opacity" Value="0.5" TargetName="RefreshRectangle" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="DeviceDataTemplate">
<Grid Margin="5,0">
<Rectangle x:Name="IconRectangle" Width="20" Height="20" Fill="{Binding IconBrush}" Opacity="0.5" ToolTip="{Binding DeviceName}"/>
</Grid>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding IsConnected}" Value="True">
<Setter Property="Opacity" Value="1" TargetName="IconRectangle" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
<DataTemplate x:Key="CommandDataTemplate">
<Grid Margin="5,0">
<myApp:myAppButton Style="{DynamicResource ChromelessButtonStyle}" Foreground="White" Content="{Binding CommandName, Converter={StaticResource LowerCaseConverter}}"
Command="{Binding Command}" CommandParameter="{Binding CommandParameter}" ToolTip="{Binding ToolTip}"
FontFamily="Marlett"/>
</Grid>
</DataTemplate>
我的模板选择器:
<models:WindowCommandItemTemplateSelector x:Key="WindowCommandTemplateSelector" DeviceTemplate="{StaticResource DeviceDataTemplate}" CommandTemplate="{StaticResource CommandDataTemplate}" RefreshCommandTemplate="{StaticResource RefreshDevicesDataTemplate}"/>
public override DataTemplate SelectTemplate(object item, DependencyObject container) {
DataTemplate resultTemplate = null;
if (item is DeviceViewModel)
{
resultTemplate = DeviceTemplate;
}
else if (item is WindowCommandViewModel) // I need two view models because I can't know which template to use with just one class.
{
resultTemplate = CommandTemplate;
}
else if (item is RefreshCommandViewModel) // here too
{
resultTemplate = RefreshCommandTemplate;
}
return resultTemplate;
}
模板选择器只根据传入的视图模型选择模板。
最后我指定了我的itemscontrol:
<myApp:myAppWindow.WindowCommands>
<myApp:WindowCommands ItemTemplateSelector="{StaticResource WindowCommandTemplateSelector}" ItemsSource="{Binding WindowCommands}" />
</myApp:myAppWindow.WindowCommands>
这是交易:我为每个数据模板设置了不同的视图模型,但实际上,RefreshButton
和CommandDataTemplate
只是具有不同模板的按钮。我有一些不同的绑定,例如IsWaiting
,但那些只能在父视图模型中处理。
如果我想继续为这个itemscontrol添加自定义模板,那么视图模型和数据模板之间是否需要1-1对应?
也许我可以创建一些静态属性并检查它?是否有更多的WPF-y方式来做到这一点?我很陌生。感谢。
答案 0 :(得分:1)
问题很混乱,但我认为您正试图避免创建多个viewmodel类型。使用DataTemplateSelector
很容易,因为你可以执行你想要的任何逻辑。例如,您可以检查MySharedViewModel.Command
的值并根据具体的命令返回模板。
如果我想继续为这个itemscontrol添加自定义模板,那么视图模型和数据模板之间是否需要1-1对应?
不,因为绑定在运行时按名称查找属性。您对Command
的绑定将与RefreshCommandTemplate.Command
和DeviceViewModel.Command
匹配。
您唯一需要1:1映射的时间是使用DataTemplate.DataType
属性,这是一个XAML快捷方式,可以避免创建DataTemplateSelector
。