RelayCommand <enum>上的RaiseCanExecuteChanged()不会导致调用CanExecute()

时间:2018-01-11 21:12:08

标签: mvvm enums uwp mvvm-light uwp-xaml

这是我的第一个问题。

在使用MVVM Light的UWP应用程序中,我尝试使用枚举参数定义一个命令,以响应视图中的所有按钮交互。但是按钮仍处于禁用状态且无响应。

我已经为命令

定义了参数
public enum ButtonKey
{
    Connect = 0,
    Disconnect = 1
}

然后由MainViewModel类使用

public class MainViewModel : ViewModelBase
{
    RelayCommand<ButtonKey> buttonPressed;
    public RelayCommand<ButtonKey> ButtonPressed
    {
        get => buttonPressed;
        set => buttonPressed = value;
    }

    public MainViewModel()
    {
        buttonPressed = new RelayCommand<ButtonKey> (ButtonPressed_Execute, ButtonPressed_CanExecute);
    }

    bool ButtonPressed_CanExecute(ButtonKey arg)
    {
        bool retValue = false;
        switch (arg)
        {
            // The following conditions are just for testing
            case ButtonKey.Connect:
                retValue = true;
                break;
            case ButtonKey.Disconnect:
                retValue = false;
                break;
        }
        return retValue;
    }

    void ButtonPressed_Execute(ButtonKey obj)
    {
        // another switch() case:
    }
}

然后xaml代码如下:

<CommandBar>
    <AppBarButton Label="Connect" Command="{Binding ButtonPressed}">
        <AppBarButton.CommandParameter>
            <viewModel:ButtonKey>Connect</viewModel:ButtonKey>
        </AppBarButton.CommandParameter>
    </AppBarButton>
    <AppBarButton Label="Disconnect" Command="{Binding ButtonPressed}">
        <AppBarButton.CommandParameter>
            <viewModel:ButtonKey>Disconnect</viewModel:ButtonKey>
    </AppBarButton.CommandParameter>
</AppBarButton>

即使在ButtonPressed_CanExecute(ButtonKey arg)构造函数中调用buttonPressed.RaiseCanExecuteChanged(),也不会调用MainViewModel方法。

我认为所有这些都是由用作命令参数的枚举类型引起的,但我无法弄清楚原因。任何帮助将受到高度赞赏。

2 个答案:

答案 0 :(得分:1)

我检查了MvvmLight的源代码并发现了问题。在RelayCommand<T>'s source中,您会在CanExecute方法中找到以下内容:

if (parameter == null || parameter is T)
{
    return (_canExecute.Execute((T)parameter));
}

由于某种原因,方法的枚举parameterint,而不是执行检查时枚举的实例。因此,第二次检查将失败。

如果您更新代码以使用int,它将按预期工作:

public RelayCommand<int> ButtonPressed { get; set; }

public MainViewModel()
{
    ButtonPressed = new RelayCommand<int>(ButtonPressed_Execute, ButtonPressed_CanExecute);            
}

bool ButtonPressed_CanExecute(int arg)
{
    bool retValue = false;
    switch (arg)
    {
        // The following conditions are just for testing
        case (int) ButtonKey.Connect:
            retValue = true;
            break;
        case (int) ButtonKey.Disconnect:
            retValue = false;
            break;
    }
    return retValue;
}

void ButtonPressed_Execute(int  obj)
{
    // another switch() case:
}

我觉得这很令人惊讶,我想这应该是MvvmLight中的一个错误。

答案 1 :(得分:0)

尝试使用x:static标记扩展

设置命令参数
<AppBarButton Label="Connect" 
              Command="{Binding ButtonPressed}"
              CommandParameter="{x:Static viewModel:ButtonKey.Connect}" />