RelayCommand<enum> 上的 RaiseCanExecuteChanged() 不会导致调用 CanExecute()
RaiseCanExecuteChanged() on a RelayCommand<enum> doesn't cause CanExecute() to be called
我的第一个问题来了。
在带有 MVVM Light 的 UWP 应用程序中,我试图定义只有一个命令,其中包含一个枚举参数以响应视图中的所有按钮交互。但是按钮仍处于禁用状态并且没有响应。
我已经为命令定义了参数
public enum ButtonKey
{
Connect = 0,
Disconnect = 1
}
然后由 MainViewModel 使用 class
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>
即使在 MainViewModel
构造函数中调用 buttonPressed.RaiseCanExecuteChanged()
,也不会调用 ButtonPressed_CanExecute(ButtonKey arg)
方法。
我认为都是因为命令参数使用的枚举类型导致的,但我想不通为什么。任何帮助将不胜感激。
我查看了MvvmLight的源代码,发现了问题。在 RelayCommand<T>
's source 中,您会在 CanExecute
方法中找到以下检查:
if (parameter == null || parameter is T)
{
return (_canExecute.Execute((T)parameter));
}
出于某种原因,该方法的枚举 parameter
是一个 int
,而不是执行检查时枚举的实例。因此,第二次检查将失败。
如果您更新代码以使用 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 中的一个错误来解决。
尝试使用 x:static 标记扩展设置命令参数
<AppBarButton Label="Connect"
Command="{Binding ButtonPressed}"
CommandParameter="{x:Static viewModel:ButtonKey.Connect}" />
我的第一个问题来了。
在带有 MVVM Light 的 UWP 应用程序中,我试图定义只有一个命令,其中包含一个枚举参数以响应视图中的所有按钮交互。但是按钮仍处于禁用状态并且没有响应。
我已经为命令定义了参数
public enum ButtonKey
{
Connect = 0,
Disconnect = 1
}
然后由 MainViewModel 使用 class
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>
即使在 MainViewModel
构造函数中调用 buttonPressed.RaiseCanExecuteChanged()
,也不会调用 ButtonPressed_CanExecute(ButtonKey arg)
方法。
我认为都是因为命令参数使用的枚举类型导致的,但我想不通为什么。任何帮助将不胜感激。
我查看了MvvmLight的源代码,发现了问题。在 RelayCommand<T>
's source 中,您会在 CanExecute
方法中找到以下检查:
if (parameter == null || parameter is T)
{
return (_canExecute.Execute((T)parameter));
}
出于某种原因,该方法的枚举 parameter
是一个 int
,而不是执行检查时枚举的实例。因此,第二次检查将失败。
如果您更新代码以使用 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 中的一个错误来解决。
尝试使用 x:static 标记扩展设置命令参数
<AppBarButton Label="Connect"
Command="{Binding ButtonPressed}"
CommandParameter="{x:Static viewModel:ButtonKey.Connect}" />