我有一组所有派生自同一基类的类。这些是用于测试的,可以手动或自动运行。我希望屏幕上的显示根据枚举而有所不同。它们是在运行时通过MEF读入的,所以理念是第三方理论上可以编写一个可以以不同方式运行的测试程序。我希望尽可能简单地使用它们在XAML中编写的方式来避免错误。
我设法通过使用ControlTemplates
和DataTemplate
来实现此目的:
<ControlTemplate x:Key="AutomaticTemplate">
<TextBlock Text="Weeble"/>
</ControlTemplate>
<ControlTemplate x:Key="ManualTemplate">
<TextBlock Text="Wobble"/>
</ControlTemplate>
<DataTemplate DataType="{x:Type local:MyTestHandler1}">
<Control x:Name="myControl" Template="{StaticResource AutomaticTemplate}"/>
<DataTemplate.Triggers>
<DataTrigger Binding="{Binding RunMode}" Value="{x:Static tr:RunType.Manual}">
<Setter TargetName="myControl" Property="Template" Value="{StaticResource ManualTemplate}" />
</DataTrigger>
</DataTemplate.Triggers>
</DataTemplate>
哪个有效,但我有很多不同的测试,我可能会看到需要一种不同的显示方式,从而增加枚举大小,显然我需要创建不同的ControlTemplate
,但DataTemplate将保持不变仅针对每个不同的DataType
但是这会使每个编写的测试需要遵循特定的模式才能工作,我想让它更加用户友好。那么,有没有办法让这更通用,以便我可以做类似的事情:
<DataTemplate DataType="{x:Type local:MyTestHandler2}" Automatic="{StaticResource x}" Manual="{StaticResource y}"/>
我假设它需要是一个DataTemplate,以允许ContentControl在我的ViewModel中工作,我使用ContentControl并将其设置为当前的测试步骤,让WPF魔术为我绘制,但也许有替代方式?
我查看了DataTemplateSelector
,但是处理程序在运行时与其DataTemplates
一起被读入,但它最终与XAML一样多。
public class RunModeTemplateSelector : DataTemplateSelector
{
public DataTemplate AutomaticTemplate { get; set; }
public DataTemplate ManualTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
RunType runType = ((TestHandler)item).RunMode;
switch(runType)
{
case RunType.Automatic:
return AutomaticTemplate;
case RunType.Manual:
return ManualTemplate;
case RunType.SingleStep:
default:
return AutomaticTemplate;
}
}
使用XAML:
<DataTemplate x:Key="AutomaticTemplate">
<TextBlock Text="Weeble"/>
</DataTemplate>
<DataTemplate x:Key="ManualTemplate">
<TextBlock Text="Wobble"/>
</DataTemplate>
<DataTemplate DataType="{x:Type local:MyTestHandler}">
<DataTemplate.Resources>
<tr:RunModeTemplateSelector
ManualTemplate="{StaticResource ManualTemplate}"
AutomaticTemplate="{StaticResource AutomaticTemplate}"
x:Key="MyTemplateSelector"/>
</DataTemplate.Resources>
<ContentPresenter ContentTemplateSelector="{StaticResource ResourceKey=MyTemplateSelector}"/>
</DataTemplate>
但这不是更少的代码,也有代码落后,而与trigers一起使用的方法没有。