WPF 双向绑定到非公开 set 方法属性在 NET 45 和 NET Core 行为的不同


本文记录 WPF 在 .NET Framework 4.5 和 .NET Core 3.0 或更高版本对使用 Binding 下的 TwoWay 双向绑定模式绑定到非公开的 set 属性上的行为变更

在 .NET Framework 4.5 下,可以使用 Binding 下的 TwoWay 双向绑定模式,绑定到非公开的 set 属性,如 private set 私有设置的属性上,实现双向更改,效果上和公开的 set 方法一样,可以成功写入

但是在 .NET Core 3.0 开始,此绑定将会提示 XamlParseException 而抛出异常

如以下的 ViewModel 代码,包含了一个 Name 属性,此属性的 set 方法是私有的

    class ViewModel : INotifyPropertyChanged
    {
        public string Name
        {
            get => _name;
            private set
            {
                _name = value;
                OnPropertyChanged();
            }
        }

        private string _name;

        public event PropertyChangedEventHandler PropertyChanged;

        protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

在 XAML 使用如下代码双向绑定,期望在 TextBox 输入的内容可以写入到 Name 属性

   <TextBox Text="{Binding Name,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"></TextBox>

以上代码是能在 .NET Framework 4.5 如预期工作。然而在 .NET Core 3.0 或更高版本,将会抛出异常

System.Windows.Markup.XamlParseException: '“设置属性“System.Windows.Controls.TextBox.Text”时引发了异常。”'

InvalidOperationException: 无法对“GogeeceldeaLabacheleabe.ViewModel”类型的只读属性“Name”进行 TwoWay 或 OneWayToSource 绑定。

对应的英文异常如下

System.InvalidOperationException: 'A TwoWay or OneWayToSource binding cannot work on the read-only property 'Name' of type 'GogeeceldeaLabacheleabe.ViewModel'.'

根据 WPF: After Visual Studio 2017 Update, "A TwoWay or OneWayToSource binding cannot work on the read-only property" - Visual Studio Feedback 的描述,其实这是 .NET Framework 4.5 的坑,在 .NET Framework 4.7 就修复了。经过我的考古,在 .NET Framework 4.6 下的行为就和 .NET Core 3.0 版本相同,是会抛出异常

敲黑板,使用双向绑定到非公开 set 方法的属性上的行为变更,不是 .NET Framework 和 .NET Core 的差别行为变更,而仅仅是 .NET Framework 4.5 和后续版本的差别

以下是原文:

So, this was a BUG in framework V4.5, when most of the code was written, and "FIXED" in V4.7

在 WPF 官方从 .NET Framework 拷贝代码到 .NET Core 开源时,也遇到此坑,请看 Removed HandleTwoWayBindingToPropertyWithNonPublicSetter compat flag by ojhad · Pull Request #1502 · dotnet/wpf

Two-way binding to properties with non-public setters was being allowed because we took on behavior that was caused by a bug in .NET Framework 4.5. Back then, a compatibility flag was introduced due to this 4.5 bug. We no longer want to support this scenario because we want correct behavior in .NET Core and we want the behavior to be on parity with net472/8. So there is no longer need for the compat flag.

在 .NET Core 3.0 的更新里,也提到了这个坑,参阅 August Update for WPF on .NET Core 3.0 · Issue #1731 · dotnet/wpf

此问题我也报告给官方,请看 Binding non-public property behavior changed between dotnet core 3.1 and net45 · Issue #5923 · dotnet/wpf

我认为,如果 ViewModel 设置了属性的 set 为私有,那也就是从设计上不要让其他逻辑进行设置,自然在 XAML 里对非公开设置的属性进行写入也是非预期的,抛出异常符合设计

本文所有代码放在githubgitee 欢迎访问

可以通过如下方式获取本文的源代码,先创建一个空文件夹,接着使用命令行 cd 命令进入此空文件夹,在命令行里面输入以下代码,即可获取到本文的代码

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 01bb068fd7f714313e44cdbcfdf5d0b5630f1bac

以上使用的是 gitee 的源,如果 gitee 不能访问,请替换为 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git

获取代码之后,进入 GogeeceldeaLabacheleabe 文件夹

引用来源:https://www.cnblogs.com/lindexi/p/15820841.html

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
管理员
上一篇:.NET中大型项目开发必备(1)--UUID全球通用唯一识别码
下一篇:asp.net core 支持多种身份认证方式
评论列表

发表评论

评论内容
昵称:
关联文章

WPF 双向公开 set 方法属性 NET 45 NET Core 行为不同
WPF_15_格式化数据
使用.NET 6开发TodoList应用(26)——实现ConfigurationOption强类型
WPF Command并传参(以DataGrid示例)
数据模式
WPF 引用第三方库控件设计器加上设计时数据属性
依赖属性使用
从一次解决Nancy参数“bug”开始发布自己第一个nuget包(下篇)
YESWEB开发框架,账套域名
ASP.NET Core MVC 过滤器ActionFilter中保存页面生成html静态页面文件
ASP.NET Core web API中使用Swagger/OpenAPI(Swashbuckle)
从一次解决Nancy参数“bug”开始发布自己第一个nuget包(上篇)
WPF DataGrid 如何将被选中行带视野中
asp.net - ASP.NET Core MVC 中嵌套 TagHelper
C# PDF文档中应用多种不同字体
WPF 布局 有限空间内让两个元素尽可能撑开例子
.NET Core 复制nuget包依赖dll输出目录
附加属性使用
C# NPOI导出excel下拉数据源
WPF 使用 Silk.NET 进行 DirectX 渲染入门

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码