我目前正在学习如何将命令实现到C#/ WPF项目中。假设我有一个类MyClass
,其中包含一个简单的命令MyCommand
。
public class MyClass
{
private RelayCommand _myCommand;
public ICommand MyCommand
{
get
{
if (_myCommand == null)
_myCommand = new RelayCommand(_ => ExecuteMyCommand());
return _myCommand;
}
}
private void ExecuteMyCommand()
{
// Do work...
}
}
现在,假设我在视图模型中创建了一个ObservableCollection<MyClass>
,它绑定到ListView。 ListView有一个GridViewColumn,其按钮绑定到MyCommand。一切都很好。
public class MyViewModel
{
private ObservableCollection<MyClass> _myCollection;
public ObservableCollection<MyClass> MyCollection
{
get { return _myCollection; }
set
{
_myCollection = value;
RaisePropertyChanged("MyCollection");
}
}
public void Refresh()
{
// Do work to refresh MyCollection to it's "live" state
}
}
现在我需要在MyCollection中的一个对象执行MyCommand之后在视图模型上调用Refresh()方法,但我不确定如何处理这种情况。
我尝试过的事情:
我考虑过的事情:
ObservableCollection<MyClass>
的扩展方法,添加如前所述的引用属性,但引用ObservableCollection而不是视图模型,这不会让人感到麻烦,但仍然不是很完美我的眼睛...... 解决此问题的最佳/正确方法是什么?
答案 0 :(得分:1)
启用此功能的另一种方法如下:
<MenuItem Content="Run MyCommand"
Command="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.RefreshCommand}"
CommandParameter="{Binding}"/>
然后,在MyViewModel
public class MyViewModel
{
private ObservableCollection<MyClass> _myCollection;
public ObservableCollection<MyClass> MyCollection
{
get { return _myCollection; }
set
{
_myCollection = value;
RaisePropertyChanged("MyCollection");
}
}
//...
private ICommand _refreshCommand;
public ICommand RefreshCommand
{
get
{
if (_refreshCommand== null)
_refreshCommand= new RelayCommand<MyClass>(p => Refresh(p));
return _refreshCommand;
}
}
public void Refresh(MyClass parameter)
{
if (null == parameter)
return;
parameter.ExecuteMyCommand();
// Do work to refresh MyCollection to it's "live" state
}
}
注意:目前您不需要在每个MyCommand
实例上都有MyClass
- 您可以将其作为参数传递给父视图模型。
我不能说正确的方式来完成你的任务。所以我不能说哪一个更好。
答案 1 :(得分:0)
我设法让这个工作(我认为)非常好。
首先,我将Refresh()更改为命令。然后我在MyCommand方法中添加了一个参数。该方法完成其工作,然后检查参数以查看它是否是命令,然后执行它。
private void ExecuteMyCommand(object param)
{
// Do work...
if (param != null && param is ICommand)
((ICommand)param).Execute(null);
}
然后在XAML中查看View,我将CommandParameter设置为我希望它之后运行的命令。
<MenuItem Content="Run MyCommand"
Command="{Binding UploadCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.RefreshCommand}"/>
如果XAML中没有提供CommandParameter,则传递null。做...
答案 2 :(得分:0)
您还可以在按钮上放置一个click事件(它们向上冒泡到视图),然后从代码隐藏中调用命令