从ViewModel调用View的CodeBehind中的方法?

for*_*yez 20 c# wpf mvvm

我在我的View后面的代码中有一个方法(这个方法对我的UI做了一些事情).

无论如何,我想从我的ViewModel触发这个方法.怎么可以这样做?

Sin*_*atr 23

我的(也许是其他人?)MVVM的难点在于理解一件简单的事情:View了解ViewModel.我使用绑定和命令,但都是简单的stringsxaml.由于在运行时安全解析(安全意味着你可以做错字,但软件不会崩溃)这使得视图视图模型分离(至少在编译时).我一直在寻找解决方案,以保持这种脱钩,例如,行为.

事实是,您可以直接访问视图模型,这通常是一个DataContext窗口/用户控件:

var vm = (MyViewModel)this.DataContext;
Run Code Online (Sandbox Code Playgroud)

知道这一点,使用事件可能是从视图模型调用视图方法的最佳方法,因为视图模型不知道是否有订阅者,它只是触发该事件和事件可以被视图或其他视图模型使用.

// define in the view model
public delegate void MyEventAction(string someParameter, ...);
public event MyEventAction MyEvent;

// rise event when you need to
MyEvent?.Invoke("123", ...);

// in the view
var vm = (MyViewModel)DataContext;
vm.MyEvent += (someParameter, ...) => ... // do something
Run Code Online (Sandbox Code Playgroud)

  • 那是极好的答案。我不得不使用: var vm = (MyViewModel)BindingContext; 用于 xamarin 表单而不是 DataContext。非常感谢。 (2认同)

hel*_*ker 9

您可以在 View(代码隐藏)中这样做。

它转换为要由 ViewModel 实现的接口,这样您就不会被限制为一种特定的 ViewModel 类型。

    // CONSTRUCTOR
    public SomeView()
    {
        InitializeComponent();

        DataContextChanged += DataContextChangedHandler;
    }

    void DataContextChangedHandler(object sender, DependencyPropertyChangedEventArgs e)
    {
        var viewModel = e.NewValue as IInterfaceToBeImplementedByViewModel;

        if (viewModel != null)
        {
            viewModel.SomeEvent += (sender, args) => { someMethod(); }
        }
    }
Run Code Online (Sandbox Code Playgroud)


sll*_*sll 5

根据MVVM 模式, ViewModel 不知道 View,所以这是不可接受的。要与 ViewModel 交互,视图可以触发命令,也可以使用绑定。此外,您不应该将特定于 UI 的内容(例如 BusyIndi​​cator)移至 ViewModel 级别。

请提供有关您的具体用例的更多详细信息 - 当您想要调用视图的方法以及该方法的作用时。