【问题标题】:RelayCommand Execute delegate doesn't work if local variables are used如果使用局部变量,RelayCommand 执行委托将不起作用
【发布时间】:2015-05-26 02:40:22
【问题描述】:

我正在尝试在一个方法中创建一个 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 的执行委托中的方法,它不会触发。我将此命令绑定到一个按钮。当我单击按钮时,甚至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 绑定到 Button.Command,它不会执行:

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

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

有什么想法吗?

更新

进一步的实验表明,在 Execute 委托中使用虚拟属性而不是参数似乎确实有效。 NavigateToViewCommand 在此代码中创建的命令在绑定到 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"; } }

【问题讨论】:

  • 我忘了提及我的环境:这是在 Windows 8.1 WinRT 应用程序中。我正在运行 64 位 Windows 8.1(在运行 Boot Camp 的 MacBook Pro 上,如果这很重要的话)。无论我在本地还是在模拟器中运行应用程序,行为都是相同的。我今天在VS 2013中使用nuget安装了MVVM Light,GalaSoft.MvvmLight.dll的版本好像是5.1.1.35049。

标签: c# mvvm-light


【解决方案1】:

我更喜欢使用 in-built 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.:这个我没试过。我希望它没有错字,并且工作正常。

【讨论】:

  • 感谢您的回复。我明白你在说什么,但是当从代码执行命令时,你的方法效果最好。就我而言,我的目标是将我的 ICommand 绑定到 Button.Command,并完全封装将要发生的事情的逻辑(在本例中是导航),而不必绑定 Button.CommandParameter。
猜你喜欢
  • 2010-09-14
  • 2021-11-14
  • 2019-07-29
  • 2016-01-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多