WPF。更改事件绑定上的 DataContext 以访问 MVVM 项目上的代码隐藏

WPF. Change DataContext on event binding to access code-behind on a MVVM project

我正在使用 MVVM 开发 WPF 应用程序。 在 XAML 代码中,我有一个网格,其 DataContext 指向一个 ViewModel,我需要知道是否可以在运行时更改 DataContext 以在其代码隐藏中访问事件。

视图的代码隐藏:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        this.DataContext = new MainViewModel();
        InitializeComponent();
    }

    private void ValidationEvent(object sender, ValidationErrorEventArgs e)
    {
        //Something useful
    }
}

这是我在 XAML 中尝试的代码:

<Grid Validation.Error={Binding Path=ValidationEvent RelativeSource={RelativeSource Self}}/>

XAML 代码抛出 XamlParseException,告知无法对 "AddErrorHandler" 执行绑定,只能对 DependencyObject 执行 DependencyProperty。

我不想更改 Grid 的 DataContext,因为其中有访问 MainViewModel 属性的元素,所以我只想更改 Validation.Error 事件绑定的 DataContext... 如果有可能...

谢谢。

Validation.Error 是一个事件,而不是 属性。您不能为事件设置绑定。

您可以使用 MVVM Light 的 EventToCommand 或 Microsoft 自己的交互性 EventTrigger 将命令与事件相关联。

但是在代码隐藏中添加常规事件处理程序并从那里调用一些视图模型代码确实没有任何问题......与许多人似乎认为的相反,MVVM 并不禁止使用代码隐藏以及您将要执行的操作与 EventToCommand 或 EventTrigger 在后台执行的操作没有太大区别。

首先,只需为 Validation.Error 事件设置事件处理程序名称。

<Grid Validation.Error="ValidationEvent" />

然后在你的代码隐藏中做任何你想做的事情。

private void ValidationEvent(object sender, ValidationErrorEventArgs e)
{
    // Something useful

    // Some call to VM code
    (this.DataContext as MainViewModel).SomeMethod();
}

这独立于您的 DataContext 工作(当然,只要您将 this.DataContext 转换为正确的类型)。

事件处理程序不依赖于您的 DataContext,只有绑定才依赖。