首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >基于属性值更改WPF装饰器子对象

基于属性值更改WPF装饰器子对象
EN

Stack Overflow用户
提问于 2016-08-22 22:44:35
回答 2查看 157关注 0票数 0

我有一个WPF控件,它的内容完全依赖于它的数据上下文的属性。为此,我们假设该控件的状态是Product类型的,其DataContext属性为InStock、OutOfStock或Discontinued。

我对每种状态类型都有单独的用户控件。我可以并且已经创建了某种类型的面板,将每个组件的可见性绑定到Product.Status。但这就产生了问题,因为一些用户控件最终以时髦的东西结束,因为一些控件依赖于设置的各种属性。在我的实际应用程序中,有许多状态,所以visualtree对我来说太大了。

我通过创建并在我的代码中检查DataContext上的状态更改并在一个大的switch语句中设置适当的子级来解决这个问题。如果可能的话,我想用XAML来做这件事。我希望孩子是按需设置的,所以我假设我将需要使用模板。类似这样的东西: SwitchControl将从装饰器或边界派生,无论是什么。

代码语言:javascript
复制
<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>

如果我能把整个过程缩短为:

代码语言:javascript
复制
<SwitchControl>
    <Possibility Value="Discontinued">
      <DiscontinuedView />
    </Possibility>
    <Possibility Value="InStock">
      <InStockView />
    </Possibility>
</SwitchControl>

重点是,在任何给定的时间都只有一个子级存在。有谁知道有什么方法可以解决这个问题吗?我在MVVM框架中四处寻找,什么也找不到。否则,我将尝试自己创建一个自定义控件。

EN

回答 2

Stack Overflow用户

发布于 2016-08-22 23:13:53

您可能想看看DataTemplateSelector class。这允许您基于不同的标准定义模板,例如当前DataContext的类型。示例可能如下所示:

代码语言:javascript
复制
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通过以下方式使用它:

代码语言:javascript
复制
<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}"/>
票数 0
EN

Stack Overflow用户

发布于 2016-08-23 00:30:12

谢谢你的建议,andreask。我最终创建了一个我认为可以更直接地解决问题的控件。我一直在开发一个WPF助手库,将来我会把它发布到nuget上,但如果你现在想使用它,可以在下面的链接中找到:

https://gist.github.com/StevePotter/b17f8d4b2657a2d2610390a11fb57e03

其中包含了XAML示例。我希望这对某些人有用!

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39082499

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档