0

我有一个 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!!!" />

我可以在视图模型中为每种类型的错误创建一个布尔属性,指示可能的错误是否属于特定类型。然后我可以将每个标签背景绑定到相应的属性。但这对我来说似乎有点混乱,因为我必须在原始可能错误属性的设置器中对这些额外的每一个调用 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 和 IsRabbits 之间有一个耦合,每当我添加新的错误类型和布尔属性时,我很可能会忘记它。有没有更好的方法来实现我的目标?

4

1 回答 1

1

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

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都可以循环遍历所有内容。pumpErrorTypesLikelyErrorIsLikely

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

<Label Content="{Binding Display}" Background="{Binding Background}"/>
于 2013-04-09T09:56:13.523 回答