我有一个WPF控件,它的内容完全依赖于它的数据上下文的属性。为此,我们假设该控件的状态是Product类型的,其DataContext属性为InStock、OutOfStock或Discontinued。
我对每种状态类型都有单独的用户控件。我可以并且已经创建了某种类型的面板,将每个组件的可见性绑定到Product.Status。但这就产生了问题,因为一些用户控件最终以时髦的东西结束,因为一些控件依赖于设置的各种属性。在我的实际应用程序中,有许多状态,所以visualtree对我来说太大了。
我通过创建并在我的代码中检查DataContext上的状态更改并在一个大的switch语句中设置适当的子级来解决这个问题。如果可能的话,我想用XAML来做这件事。我希望孩子是按需设置的,所以我假设我将需要使用模板。类似这样的东西: SwitchControl将从装饰器或边界派生,无论是什么。
<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框架中四处寻找,什么也找不到。否则,我将尝试自己创建一个自定义控件。
发布于 2016-08-22 23:13:53
您可能想看看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;
}
}...and通过以下方式使用它:
<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}"/>发布于 2016-08-23 00:30:12
谢谢你的建议,andreask。我最终创建了一个我认为可以更直接地解决问题的控件。我一直在开发一个WPF助手库,将来我会把它发布到nuget上,但如果你现在想使用它,可以在下面的链接中找到:
https://gist.github.com/StevePotter/b17f8d4b2657a2d2610390a11fb57e03
其中包含了XAML示例。我希望这对某些人有用!
https://stackoverflow.com/questions/39082499
复制相似问题