【问题标题】:WPF. Change DataContext on event binding to access code-behind on a MVVM projectWPF。更改事件绑定上的 DataContext 以访问 MVVM 项目的代码隐藏
【发布时间】:2015-09-02 20:02:09
【问题描述】:

我正在使用 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...如果可能的话。 ..

谢谢。

【问题讨论】:

  • 你想在那个事件处理程序中做什么,为什么不能在视图模型中处理?
  • 只是测试(这就是事件为空的原因)。是的,它可以在 ViewModel 上处理,但因为它是一个事件,我不能将它直接绑定到 ICommand,我不得不使用类似 MVVM Light 的“EventToCommand”之类的东西,我想知道它是否绝对必要。
  • 绑定用于告诉 WPF 去哪里获取值。您可以更改绑定的 Source 以告诉它应该转到当前 DataContext 以外的其他位置以获取值,就像您在代码中使用 RelativeSource Self 将该绑定的源更改为 Grid 对象本身一样。您可以将其更改为 MainWindow 对象(我建议使用 ElementNameRelativeSourcex:Type Window),但这不会改变这里的两个核心问题 - 事件不知道如何读取一个绑定,而 ValidationEvent 是一个方法,而不是一个属性。

标签: wpf mvvm code-behind datacontext


【解决方案1】:

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

您可以使用诸如 MVVM Light 的 EventToCommand 或 Microsoft 自己的 Interactivity 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,只有 Bindings 会。

【讨论】:

  • 您能进一步解释一下吗?你的意思是不要把View的DataContext绑定到ViewModel,从Code-Behind调用ViewModel?
  • 我认为我们在这里搞混了。事件处理和数据绑定是两个完全不同的东西。您无需更改 DataContext 即可在代码隐藏中处理事件,无论您的 DataContext 是什么,事件总是在代码隐藏中处理。
猜你喜欢
  • 2011-03-14
  • 2010-10-23
  • 2011-03-25
  • 2011-03-08
  • 2021-07-19
  • 1970-01-01
  • 1970-01-01
  • 2013-10-17
  • 2022-11-12
相关资源
最近更新 更多