我有一个WPF控件,其内容完全取决于其数据上下文的属性。为此,我们只是说控件的DataContext是Product类型,其Status属性为InStock,OutOfStock或Discontinued。
我为每种状态类型都有单独的用户控件。我可以并且已经创建了某种面板,将每个面板的可见性绑定到Product.Status。但这会产生问题,因为一些用户控件最终会出现质朴的东西,因为有些依赖于所设置的各种属性。在我的实际应用中,有许多状态,因此visualtree对我来说太大了。
我通过创建问题解决了问题,在我的代码中,我检查了DataContext上的状态更改,并在一个大的switch语句中设置了相应的子代。如果可能的话,我想在XAML中这样做。我希望按需设置孩子,所以我假设我需要使用模板。像这样的东西: SwitchControl将派生自Decorator或Border,无论如何。
<SwitchControl Property="Status">
<SwitchControl.Possibilities>
<Possibility Value="Discontinued">
<Possibility.Template>
<DiscontinuedView />
</Possibility.Template>
</Possibility>
<Possibility Value="InStock">
<Possibility.Template>
<InStockView />
</Possibility.Template>
</Possibility>
<SwitchControl.Possibilities />
</SwitchControl>
如果我可以缩短整个事情,那就更好了:
<SwitchControl>
<Possibility Value="Discontinued">
<DiscontinuedView />
</Possibility>
<Possibility Value="InStock">
<InStockView />
</Possibility>
</SwitchControl>
重点是,在任何给定时间只存在一个孩子。有人知道如何完成这项工作吗?我环顾了MVVM框架,无法找到任何东西。否则,我将尝试自己创建一个自定义控件。
答案 0 :(得分:0)
您可能需要查看DataTemplateSelector class。这允许您根据不同的标准定义模板,例如当前DataContext
的类型。一个例子看起来有点如下:
public class MyDataTemplateSelector : DataTemplateSelector
{
public DataTemplate DiscontinuedDataTemplate { get; set; }
public DataTemplate InStockDataTemplate { get; set; }
public DataTemplate OutOfStockDataTemplate { get; set; }
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
var product = item as Product;
switch (product.Status)
{
case Status.InStock:
return InStockDataTemplate;
case Status.Discontinued:
return DiscontinuedDataTemplate;
case Status.OutOfStock:
return OutOfStockDataTemplate;
}
// Fallback
return DiscontinuedDataTemplate;
}
}
...并按以下方式使用它:
<Window.Resources>
<DataTemplate x:Key="DiscontinuedDataTemplate">
<DiscontinuedView />
</DataTemplate>
<DataTemplate x:Key="InStockDataTemplate">
<InStockView />
</DataTemplate>
<DataTemplate x:Key="OutOfStockDataTemplate">
<OutOfStockView />
</DataTemplate>
<!-- DataTemplate Selector -->
<local:MyDataTemplateSelector x:Key="MyTemplateSelector"
DiscontinuedDataTemplate="{StaticResource DiscontinuedDataTemplate}"
InStockDataTemplate="{StaticResource InStockDataTemplate}"
OutOfStockDataTemplate="{StaticResource OutOfStockDataTemplate}"/>
</Window.Resources>
<ContentControl ContentTemplateSelector="{StaticResource MyTemplateSelector}" Content="{Binding Product}"/>
答案 1 :(得分:0)
感谢您的建议和回复。我最终创建了一个控件,我认为它可以更直接地解决问题。我一直在研究一个WPF帮助程序库,我将来会发布给nuget,但是如果你现在想要使用它,那就是:
https://gist.github.com/StevePotter/b17f8d4b2657a2d2610390a11fb57e03
包含示例XAML。我希望这对某人有用!