将属性值映射到条件

时间:2015-05-15 15:28:44

标签: c# wpf xaml anti-patterns

我是WPF和C#的新手。我的GUI中有一个按钮,显示为图像。但是,显示的图像取决于某些条件。根据条件,按钮可以是5个图像中的一个。我把它编码为:

查看:

<Button x:Name="bShow" HorizontalAlignment="Left" Margin="200,0,0,0" VerticalAlignment="Top" Width="200" Height="200" >
        <Image Source="{Binding myShowProp}"/>

属性myShowProp在MainWindow.xaml.cs中定义:

public string myShowProp // This property decides what image appears inside the button
{
    get { return privProp; }
    set 
    { 
        privProp = value;
        OnPropertyChanged("myShowProp");
    }
}

一个名为SetButtonImage的例程负责将某些条件映射到某些图像的逻辑。它在MainWindow.xaml.cs中编码为:

private void SetButtonImage() 
{
     if ( /* condition1 */)
         myShowProp = image1;
     else if ( /* condition2 */)
         myShowProp = image2;
     else if ( /* condition3 */)
         myShowProp = image3;
     else if ( /* condition4 */)
         myShowProp = image4;
     else
         myShowProp = image5;

}

你能否告诉我一个更好的方法来做到这一点,我无法想象if无处不在的使用是最好的设计,似乎我错过了一些东西。

这背后的另一个动机是我有一个设计师,如果这是你可以在BLend中做的事情,在控制属性级别,那么我宁愿让他在混合中做,而不是添加到代码隐藏。

P.S。我要做的其中一件事就是根据MVVM范例重构我现有的代码。

2 个答案:

答案 0 :(得分:1)

WPF应该与MVVM(模型 - 视图 - 视图模型)模式一起使用,模式使用概念作为DataBinding(已在使用中)和模板化,更具体地说是使用带触发器的ControlTemplates(在按钮上)。

这个想法将是:

  • 您将拥有五个ImageSource,在Button.Resources中声明;
  • 您的ViewModel上会有一个Enum属性(不是String!);
  • 您的按钮将包含一个包含图像的DataTemplate;
  • Image的Source将由绑定到该Enum属性的一系列触发器定义。

答案 1 :(得分:0)

如果您有复杂的条件,则需要很长的If-Else语句。如果它是单个条件的多个状态,则switch语句会为您简化它。只要确保你在setter中为那些条件中使用的任何属性调用SetButtonImage(),它就没事了。

myShowProp属性是否仅为按钮提供图像地址以获取图片?如果是这样的话,那就是你可以改变事物以更符合MVVM的地方。您希望属性只提供状态,最好是描述状态的名称,然后GUI设计器将使用该状态来确定图像。他将能够使用资源和可能的样式触发器来显示正确的图像。

我已经和MVVM合作了一年多了,我觉得我做得很好,你发布的代码对我来说很好。