C# Community Toolkit Mvvm:ObservableProperty生成器大写属性名问题
C# Community Toolkit MVVM:生成小写命名的ObservableProperty
刚用C# Community Toolkit MVVM工具包给WPF实现ObservableProperty,创建了UserControl和标注[ObservableProperty]的ViewModel,设置DataContext后发现私有字段testData无法直接访问,工具包自动生成了大写开头的公共属性TestData。想知道能不能让工具包生成原小写形式的testData属性,避免绑定和代码访问时的混淆。
相关代码
UserControl代码
<UserControl x:Class="WPF_test.StatusControl" 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:local="clr-namespace:WPF_test" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <TextBox x:Name="txtTest" Text="{Binding testData}" Grid.Column="0" Grid.Row="0" Margin="5,5,5,5" /> </Grid> </UserControl>
ViewModel代码
using System; using CommunityToolkit.Mvvm.ComponentModel; namespace WPF_test { [ObservableObject] public partial class StatusControlViewModel { [ObservableProperty] private String? testData; } }
MainWindow代码
public partial class MainWindow : Window { StatusControlViewModel model; public MainWindow() { InitializeComponent(); model = new StatusControlViewModel(); status.DataContext = model; model.testData = "test"; } }
工具包生成的代码
namespace WPF_test { partial class StatusControlViewModel { /// <inheritdoc cref="testData"/> [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.0.0.0")] [global::System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] public string? TestData { get => testData; set { if (!global::System.Collections.Generic.EqualityComparer<string?>.Default.Equals(testData, value)) { OnTestDataChanging(value); OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.TestData); testData = value; OnTestDataChanged(value); OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.TestData); } } } /// <summary>Executes the logic for when <see cref="TestData"/> is changing.</summary> [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.0.0.0")] partial void OnTestDataChanging(string? value); /// <summary>Executes the logic for when <see cref="TestData"/> just changed.</summary> [global::System.CodeDom.Compiler.GeneratedCode("CommunityToolkit.Mvvm.SourceGenerators.ObservablePropertyGenerator", "8.0.0.0")] partial void OnTestDataChanged(string? value); } }
解决方案
工具包默认按首字母大写规则生成公共属性,但可以通过[ObservableProperty]的Name参数自定义生成的属性名称:
修改ViewModel中的字段标注,指定Name为小写的testData,同时将私有字段改为下划线前缀的命名(避免和生成的属性名冲突):
[ObservableProperty(Name = "testData")] private String? _testData;
修改后的完整ViewModel代码:
using System; using CommunityToolkit.Mvvm.ComponentModel; namespace WPF_test { [ObservableObject] public partial class StatusControlViewModel { [ObservableProperty(Name = "testData")] private String? _testData; } }
此时工具包会生成名为testData的公共属性,XAML绑定({Binding testData})和后台代码访问(model.testData = "test")都能正常工作。
另外补充:WPF数据绑定默认不区分大小写,即使生成的是TestData,XAML里写{Binding testData}也能正常绑定。但如果要求代码和绑定命名完全一致,使用Name参数自定义是最直接的解决方式。
内容的提问来源于stack exchange,提问作者Tim Butler
相关产品推荐
相关产品推荐

