RelayCommand在某些计算机上不启动
本文关键字:启动 计算机 RelayCommand | 更新日期: 2023-09-27 18:16:28
首先,这是我在SO上的第一篇文章,所以要温柔;)
我有一个非常简单的WPF应用程序,在不同的视图中有一个带有两个选项和一些按钮的菜单,其中大多数都有数据绑定到Microsoft.TeamFoundation.MVVM.RelayCommand。在我的计算机上调试时,一切都很好,当运行构建的exe时,它工作得很好,在我同事的计算机上构建的版本工作得很好,但是在我办公室的另一台计算机上测试时没有这些RelayCommands会触发…
XAML:
//Menu item
<MenuItem Header="Quit" Command="{Binding QuitCommand}" />
//Button
<Button Content="Update" Command="{Binding UpdateCommand}"
IsEnabled="{Binding Ready}" Height="30" />
C #:
//Menu item
public ICommand QuitCommand
{
get
{
return new RelayCommand(() => Quit());
}
}
//Button
public ICommand UpdateCommand
{
get
{
return new RelayCommand(() => Update());
}
}
关于计算机的一些信息:
My computer: Win8 Pro 64, .NET 4.5
My colleagues computer: Win7 Pro 64, .NET 4.5
Office computer: Win7 Pro 32, .NET 4.5
该解决方案是为目标框架4.5和处理器架构x86构建的。其他数据绑定(如上面的IsEnabled)和各种文本属性似乎工作得很好。
请告诉我,如果我可以提供任何其他信息!
更新:我做了我自己的RelayCommand工作良好的实现:
public class RelayCommand : ICommand
{
readonly Action<object> mExecute;
readonly Predicate<object> mCanExecute;
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
mExecute = execute;
mCanExecute = canExecute;
}
public RelayCommand(Action<object> execute)
{
if (execute == null)
throw new ArgumentNullException("execute");
mExecute = execute;
mCanExecute = delegate { return true; };
}
public RelayCommand(Action execute)
{
if (execute == null)
throw new ArgumentNullException("execute");
mExecute = new Action<object>(param => execute());
mCanExecute = delegate { return true; };
}
public bool CanExecute(object parameter)
{
return mCanExecute == null ? true : mCanExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
mExecute(parameter);
}
}
我不知道我的实现和TeamFoundation的有什么不同。
不确定这是否可以帮助您,但我有一个类似的问题,并通过在命令初始化期间显式触发PropertyChanged事件来解决它:
base.RaisePropertyChanged("QuitCommand");
当然,上述方法只有在你有一个实现INotifyPropertyChanged
接口的基类时才可用。你可以从Josh Smith的MVVM Foundation框架中获取它。
完整的示例代码如下:
private ICommand _quitCommand;
//Menu item
public ICommand QuitCommand
{
get { return _quitCommand; }
private set
{
if (value == _quitCommand) return;
_quitCommand = value;
base.RaisePropertyChanged("QuitCommand");
}
}
public MyViewModel()
{
QuitCommand = new RelayCommand(() => Quit());
}
有趣的是,我很确定你的原始代码在一段时间前为我工作得很好(不同的机器,环境,操作系统等)。
看起来在特定的情况下,某些东西阻止View类在ViewModel创建/启动过程中读取命令(?)属性。这需要你手动告诉一个视图,它应该读取一个目标ViewModel属性。
return new relaycommand是非常糟糕的——因为你总是创建一个新的实例。
如果需要,可以使用延迟初始化。
private Lazy<RelayCommand> _quitcommand;
//ctor
_quitcommand = new Lazy<RelayCommand>(()=> new RelayCommand(() => Quit()));
public ICommand QuitCommand
{
get
{
return _quitcommand.Value;
}
}
编辑:你也可以在运行时使用Snoop