我在独立程序集中使用WPF定义了自定义控件。在另一个项目中,我只是引用它并在XAML中使用它,如下所示:
<my:CustomUserControl Name="myControl" IsEnabled="{Binding CanTheUserInputTrade}"/>
CustomUserControl类有一个名为“Reset”的成员函数。
我曾经使用以下方法在View.xaml.cs文件中调用此函数:
myControl.Reset()
但是,出于正当理由,我必须将调用此函数的逻辑移到ViewModel中。据我所知,在ViewModel中引用视图并不是一个好习惯。因此,我将无法从ViewModel访问“myControl”引用。
我的问题是:如何在ViewModel中调用Reset函数。
这是一个常见的用例,我相信有一种方法可以做到这一点。有人能指出我正确的方向。
非常感谢。
答案 0 :(得分:3)
在过去,我已经从View的代码隐藏中吸引了这个事件。
视图模型:
public ICommand ResetCommand {get; set;}
来自UserControl的OnLoad方法:
private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
{
MyUserControl ctrl = sender as MyUserControl;
if (ctrl == null) return;
MyViewModel vm = ctrl.DataContext as MyViewModel ;
if (vm == null)
return;
vm.ResetCommand = new RelayCommand(param => this.Reset());
}
答案 1 :(得分:1)
@Rachel的解决方案很棒。使用界面可以使它更松散地耦合:
using System.Windows.Input;
namespace WpfApplication
{
public interface IResetCaller
{
ICommand ResetCommand { get; set; }
}
}
让您的基本视图模型实现此接口,例如
public class MyViewModel : ModelBase, IResetCaller
{
...
public ICommand RefreshSegmentCommand { get; set; }
}
Rachel的代码变成:
private void MyUserControl_Loaded(object sender, RoutedEventArgs e)
{
var ctrl = sender as FrameworkElement;
if (ctrl == null) return;
var vm = ctrl.DataContext as IResetCaller;
if (vm == null)
return;
vm.ResetCommand = new RelayCommand(param => this.Reset(param));
}
此接口可用于装饰任意数量的视图模型,并且可以在与UserControl相同的库中定义接口。在主ViewModel中,您只需执行类似ResetCommand.Execute(this)
或您希望传递的任何参数的内容。