将 WPF 从 .NET 4 更新到 4.5.2,DataGridTextColumn Visibility DataContext 引用损坏

Posted

技术标签:

【中文标题】将 WPF 从 .NET 4 更新到 4.5.2,DataGridTextColumn Visibility DataContext 引用损坏【英文标题】:Update WPF from .NET 4 to 4.5.2, DataGridTextColumn Visibility DataContext reference broken 【发布时间】:2016-04-21 10:07:15 【问题描述】:

我已将 WPF 项目升级到 .NET 4.5.2。在 xaml 文件中,我有以下行。

<UserControl
        x:Class="Casa.Project.Client.Views.Projects.ProjectSearch"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:controls="clr-namespace:Casa.Project.Core.Wpf.Controls;assembly=Casa.Project.Core.Wpf"
        mc:Ignorable="d"
        d:DesignWidth="700"
        x:Name="ProjectSearchWindow"
    >
<UserControl.Resources>
<DataGridTextColumn x:Key="PlanNumberColumn" Header="Project #" Visibility="Binding DataContext.ShowPlanNumber, Source=x:Reference ProjectSearchWindow" Binding="Binding ProjectNumber" />

...

ReSharper 在整个 Visibility 标记下划线,说“对象引用未设置为对象的实例”,这会产生错误。当我加载针对 .NET 4 的旧项目时,该错误不存在。

当我实际运行项目时,使用 DataGridTextColumn 的整个表不显示任何值(正在正确加载)。

从 .NET 4 到 .NET 4.5.2 是否发生了一些导致这种行为的变化?我该如何解决?

【问题讨论】:

【参考方案1】:

所以我没有弄清楚为什么升级会破坏它,但我确实想出了一个让它工作的方法。

Freezable 类能够将 DataContext 传递给它,即使它不是可视/逻辑树的一部分。我们利用这一点进行修复。

步骤

首先,创建一个继承自 Freezable 的类

public class BindingProxy : Freezable

    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    
        return new BindingProxy();
    

    #endregion

    public object Data
    
        get  return (object)GetValue(DataProperty); 
        set  SetValue(DataProperty, value); 
    

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));

其次,将&lt;helpers:BindingProxy x:Key="proxy" Data="Binding" /&gt; 放在您的DataGridTextColumn 周围。将本地更改为 BindingProxy 类的命名空间。更改 DataGrid 以匹配您的根 xaml 标记。如有必要,将 BindingProxy 的命名空间导入您的 xaml 文件(如 xmlns:helpers="clr-namespace:Casa.Project.Client.Helpers"

<DataGrid.Resources>
    <helpers:BindingProxy x:Key="proxy" Data="Binding" />
    <DataGridTextColumn x:Key="PlanNumberColumn" Header="Project #" Visibility="Binding Data.ShowPlanNumber, Source=StaticResource proxy" Binding="Binding ProjectNumber" />
</DataGrid.Resources>

最终代码状态大致

<UserControl
        x:Class="Casa.Project.Client.Views.Projects.ProjectSearch"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:helpers="clr-namespace:Casa.Project.Client.Helpers"
        xmlns:controls="clr-namespace:Casa.Project.Core.Wpf.Controls;assembly=Casa.Project.Core.Wpf"
        mc:Ignorable="d"
        d:DesignWidth="700"
        x:Name="ProjectSearchWindow"
    >
<UserControl.Resources>
    <helpers:BindingProxy x:Key="proxy" Data="Binding" />
    <DataGridTextColumn x:Key="PlanNumberColumn" Header="Project #" Visibility="Binding DataContext.ShowPlanNumber, Source=x:Reference ProjectSearchWindow" Binding="Binding ProjectNumber" />

来源:http://www.thomaslevesque.com/2011/03/21/wpf-how-to-bind-to-data-when-the-datacontext-is-not-inherited/

【讨论】:

以上是关于将 WPF 从 .NET 4 更新到 4.5.2,DataGridTextColumn Visibility DataContext 引用损坏的主要内容,如果未能解决你的问题,请参考以下文章

将解决方案中的所有项目重新定位到 .NET 4.5.2

[环境配置]Win10 这台计算机中已经安装了 .NET Framework 4.5.2 或版本更高的更新

[译]WPF开源控件扩展库ControlzEx

在 WPF 上从 .NET 5 升级到 .NET 6 后开始调试失败

使用 .NET 4.5.2 从 C# 代码更改键盘布局

将 Spyder 更新到 4.0 后出现错误 qtconsole