wpf C#社区工具包Mvvm源代码生成器:ObservableProperty大写属性名称

9wbgstp7  于 2023-01-21  发布在  C#
关注(0)|答案(1)|浏览(626)

我刚刚开始使用这个工具包,我正在尝试生成一个简单的ObservableProperty来与WPF一起使用。

<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>

和视图模型:

using System;
using CommunityToolkit.Mvvm;
using CommunityToolkit.Mvvm.ComponentModel;

namespace WPF_test
{
    [ObservableObject]
    public partial class StatusControlViewModel
    {
        [ObservableProperty]
        private String? testData;
    }
}

我将控件嵌入到主窗口中,并在代码隐藏中设置数据上下文:

public partial class MainWindow : Window
    {
        StatusControlViewModel model;
        public MainWindow()
        {
            InitializeComponent();
            model = new StatusControlViewModel();
            status.DataContext = model;
            model.testData = "test";
        }
    }

但是我发现model.testData由于它的保护级别而无法访问。2当我注解掉这一行以使代码运行时,我得到了一个绑定错误,说无法找到testData。
这是生成的代码:

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);
    }
}

看起来工具包将我的属性名称大写了。我可以通过将控件XAML中的属性名称大写来使数据绑定工作:

<TextBox x:Name="txtTest" Text="{Binding TestData}" Grid.Column="0" Grid.Row="0" Margin="5,5,5,5" />

并以类似方式访问model属性:

model.TestData = "test";

是否有一种方法可以使用工具包,以便以原始形式访问属性,即

<TextBox x:Name="txtTest" Text="{Binding testData}" Grid.Column="0" Grid.Row="0" Margin="5,5,5,5" />

<TextBox x:Name="txtTest" Text="{Binding TestData}" Grid.Column="0" Grid.Row="0" Margin="5,5,5,5" />

我想不然会很混乱。

h22fl7wq

h22fl7wq1#

没有。
没有办法"使用工具包,以便以原始形式访问属性"
因为那是字段而不是属性。
代码生成器实际上正在生成一些代码。
属性名称不能与支持字段相同。testData是字段。不能绑定到字段。

[ObservableProperty]
    private String? testData;

在分部类中生成TestData属性。

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);
            }
        }
    }

你只能绑定到公共属性,所以你需要它生成什么才能绑定。没有属性就没有绑定。
装订:
https://learn.microsoft.com/en-us/dotnet/desktop/wpf/data/?view=netdesktop-6.0
属性:
https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/properties
上述_seconds是一个字段。
小时是一个属性。
不同之处在于属性有getter和(可选的)setter。
说了这么多。
不强制您使用该属性。
您可以手动创建特性。
然后你可以用任何你喜欢的箱子来装你的财产。
我建议你学着喜欢大写的属性。
我为很多客户工作过。房产名称的标准一直是以大写字母开头。
PS
[Relaycommand]生成一个附加了"Command"的上层属性。

相关问题