在子项执行命令后调用方法
本文关键字:调用 方法 命令 执行 | 更新日期: 2023-09-27 18:34:16
我目前正在学习如何在C#/WPF项目中实现命令。假设我有一个带有简单命令MyCommand
的类MyClass
。
public class MyClass
{
private RelayCommand _myCommand;
public ICommand MyCommand
{
get
{
if (_myCommand == null)
_myCommand = new RelayCommand(_ => ExecuteMyCommand());
return _myCommand;
}
}
private void ExecuteMyCommand()
{
// Do work...
}
}
现在,假设我在绑定到 ListView 的视图模型中创建了一个ObservableCollection<MyClass>
。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(( 方法,但我不确定如何处理这种情况。
我尝试过的事情:
- 在 MyClass 的构造期间添加对视图模型的引用,允许命令在命令执行时通过视图模型的引用调用 Refresh((。这工作正常,但我真的不喜欢代码 - 让它引用特定的视图模型感觉很混乱,尤其是当它在程序的其他部分使用时。
我考虑过的事情:
- 将 Refresh(( 更改为
ObservableCollection<MyClass>
的扩展方法,添加前面提到的引用属性,但引用 ObservableCollection 而不是视图模型,这不会感觉那么混乱,但在我眼中仍然不是很完美......
解决此问题的最佳/正确方法是什么?
打开此功能的另一种方法是:
<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
}
}
注意:目前您不需要在每个MyClass
实例上都有MyCommand
- 您可以将其作为参数传递给父视图模型。
我不能说有完成任务的正确方法。所以我不能说哪一个更好。
我设法以一种非常好的方式(我认为(让它工作。
首先,我将 Refresh(( 更改为命令。然后,我在 MyCommand 方法中添加了一个参数。该方法执行其工作,然后检查参数以查看它是否是命令,然后执行它。
private void ExecuteMyCommand(object param)
{
// Do work...
if (param != null && param is ICommand)
((ICommand)param).Execute(null);
}
然后在视图的 XAML 中,我将命令参数设置为我希望它之后运行的命令。
<MenuItem Content="Run MyCommand"
Command="{Binding UploadCommand}"
CommandParameter="{Binding RelativeSource={RelativeSource AncestorType={x:Type Window}}, Path=DataContext.RefreshCommand}"/>
如果在 XAML 中未提供命令参数,则传递 null。做。。。
您还可以在按钮上放置一个单击事件(它们冒泡到视图(,并从代码隐藏调用命令