You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 21:05:20