c# - 处理高级数据模板中的数据上下文更改

标签 c# wpf datacontext

我正在 WPF 中编写 MDI 应用程序 - 文档显示在选项卡中。

由于选项卡显示完整的文档,TabControl 的 DataTemplate 显然相当复杂 - 包括 CodeBehind 中的一些初始化/取消初始化代码(没有黑客 - 这只是我使用的控件(即 AvalonEdit)所需要的)。但问题是,TabControl 重用创建的 DataTemplate,并且当我更改事件文档时,仅替换 DataContext - 忽略在加载/卸载事件中执行的所有初始化/取消初始化过程。

我想过 Hook DataContextChanged 事件,但有一个问题:

When the DataContext for an element changes, all data-bound properties on this element are potentially affected. This applies to any elements that are child elements of the current element in the logical tree, which inherit the data context, and also the current element itself. All such existing bindings must re-interpret the new DataContext and will reevaluate the binding results. The data binding engine is not deterministic about the order of these reevaluations, relative to the raising of the DataContextChanged event. The reevaluations can occur before the event, after the event, or in any mixture.

(来源:https://learn.microsoft.com/pl-pl/dotnet/api/system.windows.frameworkelement.datacontextchanged?view=netframework-4.8)

因此可能会发生这样的情况:所有数据绑定(bind)都在没有去初始化/初始化调用的情况下刷新(包括 AvalonEdit 接收新文档),这将导致异常。

理想的解决方案是强制 TabControl 每次从 DataTemplate 实例化 View ,但 View 重用机制似乎是 WPF 中的一般规则(ContentControl 也使用它)。不太理想但仍然可靠的选择是捕获 DataContext 更改 - 但我必须在 DataContext 更改之前和之后可靠地调用代码,而且似乎也是不可能的。

如何解决这个问题?如何在 WPF 中正确维护(初始化/取消初始化)具有复杂 View 的文档?

最佳答案

请参阅我对以下问题的回答:

https://stackoverflow.com/a/47763600/5314530

我提供了一个解释/理论和一个工作示例,说明如何使用 x:Shared 属性“完全刷新”DataTemplate 以及实现DataTemplateSelector(我发现两者都是确保生成新的 DataTemplate 所必需的)。

总结一下:

  1. DataTemplate 需要位于带有 x:Shared="False"ResourceDictionary 中。

    <
  2. 需要使用 DataTemplateSelector 来明确需要哪个资源/模板,以确保当前的 DataTemplate 不会被保留。

关于c# - 处理高级数据模板中的数据上下文更改,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56931236/

相关文章:

c# - 在 WPF 中呈现一组控件的最佳实践?

c# - WPF 有条件地启用键绑定(bind)

c# - 如何从 Entity Framework 中获取架构名称?

wpf - 如何使Aero Glass背景上的WPF文本可读?

javascript - Polymer -> 类似于绑定(bind)中的 WPF/SL DataContext 的概念

c# - 为什么在设置 DataContext 时我的验证规则没有运行?

c# - Linq更新数据库,主键

c# - 从具有重复键的数据库查询创建 C# 字典

c# - 使用 MSHTML/IExplorer 捕获模态对话框对象

c# - 确定多播套接字数据的发送者