如何绑定WPF GUI值以反映底层值是否为某个枚举值



我有一个WPF应用程序,它应该提醒用户泵中即将发生的错误。有三种类型的错误,我将它们定义为PumpErrorModel中的枚举。这个pumpErrorModel还知道哪种类型的错误最可能发生。这是由我的PumpErrorViewModel向GUI公开的,GUI有一个标签绑定到这个最可能的错误的值,并将其转换为字符串。到目前为止,一切顺利。

// from MainWindow.xaml
<Label ... Content="{Binding LikelyError, Converter={StaticResource PumpErrorTypeToString}}" />
// from PumpErrorViewModel.cs
private PumpErrorModel.PumpErrorType likelyError;
public PumpErrorModel.PumpErrorType LikelyError {
    get { return likelyError; }
    private set { likelyError = value; RaisePropertyChanged("LikelyError"); } }

在我的GUI中,我也有每种类型的泵错误的描述,即每个枚举值一个。我想将这些标签的背景绑定到最可能的错误类型的值,这样当最可能的错误类型是"爆炸"时,描述爆炸的标签具有红色背景,而其他标签具有白色背景。

// from MainWindow.xaml. I would like to bind the background of these
<Label Content="Likely Error: Explosions" />
<Label Content="Likely Error: More Explosions!" />
<Label Content="Likely Error: Rabbits!!!" />

我可以在视图模型中为每种类型的错误创建一个布尔属性,以指示可能的错误是否属于特定类型。然后我可以将每个标签背景绑定到相应的属性。但这对我来说似乎有点混乱,因为我必须在原始可能错误属性的setter中对这些额外的属性调用RaisePropertyChanged。

// proposed code in PumpErrorViewModel.cs
public bool IsRabbits { get { return LikelyError == PumpErrorModel.PumpErrorType.Rabbits; } };
// amended LikelyError setter
public PumpErrorModel.PumpErrorType LikelyError {
   get ...
   private set { likelyError = value;
                 RaisePropertyChanged("LikelyError");
                 RaisePropertyChanged("IsRabbits"); } }
// proposed code in MainWindow.xaml
<Label Content="Likely Error: Rabbits!!!" BackGround="{Binding IsRabbits, Converter){StaticResource BoolToColor}}" />

如果我这样做,那么我在LikelyError和israbbit之间有一个耦合,每当我添加新的错误类型和布尔属性时,我可能会忘记这个耦合。有没有更好的方法来实现我的目标?

在主视图模型上使用子集合似乎是一个很好的情况。该子集合中的每个视图模型将表示单个泵错误类型。然后,您的视图将绑定到该集合,以列出所有潜在的泵错误并突出显示可能的错误。下面是我们讨论的起点:

public class MainViewModel : ViewModel
{
    private readonly ICollection<PumpErrorTypeViewModel> pumpErrorTypes;
    public MainViewModel()
    {
        this.pumpErrorTypes = Enum.GetValues(typeof(PumpErrorType))
            .Cast<PumpErrorType>()
            .Select(x => new PumpErrorTypeViewModel(x))
            .ToList();
    }
    pubilc ICollection<PumpErrorTypeViewModel> PumpErrorTypes
    {
        get { return this.pumpErrorTypes; }
    }

public class PumpErrorTypeViewModel : ViewModel
{
    private readonly PumpErrorType type;
    public PumpErrorTypeViewModel(PumpErrorType type)
    {
        this.type = type;
    }
    public PumpErrorType Type
    {
        get { return this.type; }
    }
    public string Display
    {
        // do whatever formatting you like here
        get { return string.Format("Likely Error: {0}", this.type); }
    }
}
<ItemsControl ItemsSource="{Binding PumpErrorTypes}">
    <ItemsControl.ItemTemplate>
        <DataTemplate>
            <Label Content="{Binding Display}"/>
        </DataTemplate>
    </ItemsControl.ItemTemplate>
</ItemsControl>

现在,为了给标签的背景上色,我们有很多方法可以实现这一点,但最常见的两种方法是:

  1. MainViewModel可能具有LikelyError属性。PumpErrorTypeViewModel可以在其构造函数中接受MainViewModel,并暴露Background的属性。它可以监听LikelyError中的变化,并相应地使Background失效。这非常适合响应式实现(参见ReactiveUI)。
  2. PumpErrorViewModel可以暴露IsLikely属性,当设置Background属性时,该属性无效。MainViewModel可以在LikelyError变化时循环所有pumpErrorTypes,并更新子IsLikely属性。

无论哪种方式,视图都有一个简单的更改:

<Label Content="{Binding Display}" Background="{Binding Background}"/>

相关内容

  • 没有找到相关文章

最新更新