如何根据用例有选择地禁用重用ViewModel上的控件?

时间:2017-02-08 13:10:37

标签: c# wpf xaml mvvm

我正在使用MVVM处理WPF应用程序,我重复使用视图模型来查看/创建/编辑/复制业务对象(称为Flow)。视图上有大约25个字段,其中一些字段需要被禁用,具体取决于用户是在查看/编辑/ ...流程。为了保持视图和视图模型的清洁,我提出了以下解决方案:

  • 我使用包含所有不同GuiAction s(FlowView,FlowEdit等等)的枚举GuiAction。
  • 我在GuiAction类型的Flow视图模型上有一个属性,表示我们是否正在查看/编辑/.../ li>
  • 流上的所有字段都将IsEnabled属性数据绑定到GuiAction属性,转换器ControlAvailability将该属性的名称作为参数:

    <CheckBox
        IsEnabled="{Binding GuiAction,
            Converter={StaticResource ControlAvailability},
            ConverterParameter=Runnable}"></CheckBox>
    
  • ControlAvailability同时接收GuiAction和参数名称,并且应该返回true或false,启用或禁用控件。

至于ControlAvailability中的逻辑,我最初查找可用性的想法是使用两层交换语句,如下所示:

public object Convert(object value, ..., object parameter, ...)
{
    GuiAction guiAction = (GuiAction)value;
    string control = (string)parameter;

    switch (guiAction)
    {
        case GuiAction.FlowView:
            switch (control)
            {
                case "Runnable":
                    return false;
                    break;
                case "Path":
                    return false;
                    break;
                ...
            }
            break;
        case GuiAction.FlowEdit:
            switch (control)
            {
                case "Runnable":
                    return true;
                    break;
                ...
            }
            break;
        ...
    }
}

但是有7个GuiActions和25个控件,这将变成数百行代码..我觉得必须有更好的方法来做到这一点......可能在某个地方的平面文件中。

那么..大规模的切换语句是可行的还是有更好的解决方案?

2 个答案:

答案 0 :(得分:0)

我认为你只需要在转换器中使用它:

public object Convert(object value, ..., object parameter, ...)
{
    GuiAction guiAction = (GuiAction)value;
    return guiAction == GuiAction.FlowEdit;
}

并且仅绑定要禁用的控件,因此您不需要绑定参数。

<强>更新

您可以在另一个文件中声明的静态变量中包含字典:

public static class StaticData
{
    public static Dictionary<GuiAction, Dictionary<string, bool>> dict = new Dictionary<GuiAction, Dictionary<string, bool>>
        {
            {
                GuiAction.FlowView, new Dictionary<string, bool>
                {
                    {"Runnable", false},
                    {"Path", false}
                }
            },
            {
                GuiAction.FlowEdit, new Dictionary<string, bool>
                {
                    {"Runnable", true}
                }
            }
        };
}

然后你可以像这样转换:

public object Convert(object value, ..., object parameter, ...)
{
    GuiAction guiAction = (GuiAction)value;
    string control = (string)parameter;
    return StaticData.dict[guiAction][control];
}

答案 1 :(得分:0)

我最终只是使用CSV文件来存储这些数据。它非常适合存储这样的二维矩阵,并且易于实现。 Visual Studio没有CSV编辑器,但我的所有团队成员都有Microsoft Excel,可以非常方便地打开和编辑CSV文件。我根据this问题中的第二个答案实现了一个CSV阅读器,并将CSV文件读入我用来查找值的字典中。毕竟,我的Convert方法看起来像这样:

public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
    GuiAction guiAction = (GuiAction)value;
    string control = (string)parameter;

    //If this is the first time we use the control availability matrix we initialise it
    if (controlAvailabilityMatrix == null)
    {
        controlAvailabilityMatrix = InitControlAvailability();
    }
    try
    {
        return controlAvailabilityMatrix[guiAction][control];
    }
    catch (KeyNotFoundException)
    {
        throw new AvailabilityNotSetForControlException("Control availability for control " + control + " not set for GUI action " + guiAction);
    }
}