c# - 如果使用局部变量,RelayCommand Execute 委托(delegate)不起作用

标签 c# mvvm-light

我正在尝试在方法中创建一个 MVVM Light RelayCommand:

protected RelayCommand NavigateToViewCommand(string viewName) {
#if false
    return new RelayCommand(() => {
        Debug.WriteLine("It fired.");
        Navigation.Navigate(ServiceLocator.Current.GetInstance<IViewLocator>().GetViewForNavigation("StudentPage2"));
    });
#else
    return new RelayCommand(() => {
        Debug.WriteLine("It fired.");
        Navigation.Navigate(ServiceLocator.Current.GetInstance<IViewLocator>().GetViewForNavigation(viewName));
    });
#endif
}

如果我将 viewName 参数用于 RelayCommand 的 Execute 委托(delegate)中的方法,它不会触发。我将此命令绑定(bind)到一个按钮。当我单击该按钮时,甚至 Debug.WriteLine 命令都不会触发(并且放置在其上的断点也不会中断)。

但是,如果我将 viewName 参数替换为与 viewName 中的值相同的硬编码字符串,则 RelayCommand工作良好。

请注意,在按钮中未使用命令的这段代码执行时没有问题:

void Test() {
    Command1.Execute(null);
    Command2("David").Execute(null);
}
RelayCommand Command1 { get { return new RelayCommand(() => Debug.WriteLine("cmd1 executed.")); } }
RelayCommand Command2(string msg) { return new RelayCommand(() => Debug.WriteLine("cmd2 executed: " + msg)); }

但是如果我在 Xaml 中将 Command2 绑定(bind)到 Button.Command,它不会执行:

public ICommand TestCommand2 { get { return Command2("Cater"); } }

<Button Grid.Row="1" Grid.Column="1" Command="{Binding TestCommand2}" Content="TEST" />

知道这里会发生什么吗?

更新

进一步的实验表明,在执行委托(delegate)中使用虚拟属性而不是参数似乎确实有效。此代码中由 NavigateToViewCommand 创建的命令在绑定(bind)到 button.Command 时工作正常。当然,这并不能解决问题;这只是更多信息。

// In base class:
protected RelayCommand NavigateToViewCommand() {
    return new RelayCommand(() => Navigation.Navigate(ServiceLocator.Current.GetInstance<IViewLocator>().GetViewForNavigation(NextPageViewName)));
}
protected virtual string NextPageViewName { get { return string.Empty; } }

// In subclass:
private ICommand m_nextPage;
public ICommand NextPageCommand { get { return m_nextPage ?? (m_nextPage = NavigateToViewCommand()); } }
protected override string NextPageViewName { get { return "StudentPage2"; } }

最佳答案

我更喜欢使用内置 ICommand 模式而不是将此参数传递给 RelayCommand ctor,它意思是:

protected RelayCommand NavigateToViewCommand() 
{
    return new RelayCommand((viewName) => {
        Debug.WriteLine("It fired.");
        Navigation.Navigate(ServiceLocator.Current
                  .GetInstance<IViewLocator>()
                  .GetViewForNavigation(viewName.ToString()));
    });
}

然后像这样调用执行:

NavigateToViewCommand().Execute("David");

这是一种向您的命令传递参数的更温和的方式。 ps.: 这个我没试过。我希望它没有错字并且工作正常。

关于c# - 如果使用局部变量,RelayCommand Execute 委托(delegate)不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30448580/

相关文章:

C# 无法访问 Newtonsoft.Json.Linq.JProperty 上的子值

c# - 是否有与 m_nCmdShow 等效的 c#?

c# - 如何在 Visual Studio 2015 中禁用 namespace 缩写?

c# - Asp.Net vNext 在现有应用程序中自托管

c# - 导航期间出现 RaiseCanExecuteChanged COM 异常?

WPF DataGrid ContextMenu 命令绑定(bind)到 MVVMLight RelayCommand<T> 并不总是有效

c# - INotifyPropertyChanged 'Double' 绑定(bind)

C# 作为第一门语言?

c# - MVVM 模式,我不明白我应该如何编写 "Detail"ViewModel

wpf - 命名空间中不存在名称 ViewModelLocator