C# WPF中的绑定问题——属性和字段之间的差异

C# WPF中的绑定问题——属性和字段之间的差异,c#,wpf,xaml,binding,C#,Wpf,Xaml,Binding,我有一个关于绑定在WPF中如何工作的问题 如果我有一个具有如下属性的viewmodel: private string testString; public string TestString { get { return testString; } set { testString = value; } } <TextBlock Text="{Binding Path=TestString, Mode=TwoWay}" Foreground="Red"

我有一个关于绑定在WPF中如何工作的问题

如果我有一个具有如下属性的viewmodel:

private string testString;
public string TestString
{
    get { return testString; }
    set { testString = value; }
}
<TextBlock
    Text="{Binding Path=TestString, Mode=TwoWay}"
    Foreground="Red"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontFamily="Calibri"
    FontSize="24"
    FontWeight="Bold">
</TextBlock>
public string TestString;
public string TestString { get; set; }
private string testString;

public string TestString
{
    get { return testString; }
    set {
        if (testString != value) {
            testString = value;
            RaisePropertyChanged("TestString");
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null) {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
然后,如果我将它绑定到一个xaml,使用如下内容:

private string testString;
public string TestString
{
    get { return testString; }
    set { testString = value; }
}
<TextBlock
    Text="{Binding Path=TestString, Mode=TwoWay}"
    Foreground="Red"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontFamily="Calibri"
    FontSize="24"
    FontWeight="Bold">
</TextBlock>
public string TestString;
public string TestString { get; set; }
private string testString;

public string TestString
{
    get { return testString; }
    set {
        if (testString != value) {
            testString = value;
            RaisePropertyChanged("TestString");
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null) {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
完全相同的绑定不起作用。我不知道为什么会发生这种情况,因为对我来说,它相当于一个公共属性到一个具有自定义get和set的公共属性

有人能帮我解释一下这个问题吗?:)

请提前通知我


PS:很抱歉我的语法突出显示。我只是不知道如何使用代码块。

删除getter和setter会将
TestString
成员从属性更改为字段。这就是为什么绑定停止工作,并且可能不是您想要做的(这样的公共字段通常被认为是糟糕的设计)

通过声明空的getter/setter,可以让编译器自动创建支持字段,如下所示:

private string testString;
public string TestString
{
    get { return testString; }
    set { testString = value; }
}
<TextBlock
    Text="{Binding Path=TestString, Mode=TwoWay}"
    Foreground="Red"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontFamily="Calibri"
    FontSize="24"
    FontWeight="Bold">
</TextBlock>
public string TestString;
public string TestString { get; set; }
private string testString;

public string TestString
{
    get { return testString; }
    set {
        if (testString != value) {
            testString = value;
            RaisePropertyChanged("TestString");
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null) {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

我不确定它是否与INotifyPropertyChanged有关,可能是在删除Get Set之后,WPF无法识别源是否已更改。或者它被视为只读属性

请你仔细阅读这些文章


@Silva,你的直觉是正确的,幕后有事情发生。我在Pete Brown(Microsoft Developer Evangelist)的博客上看到的一篇博文中清楚地提到了这一点:

查看他在哪里写的
PropertyDescriptor
类。他还进一步提到,与在viewmodel类上使用更传统的方法实现
INotifyPropertyChanged
接口相比,它的效率相对较低,如下所示:

private string testString;
public string TestString
{
    get { return testString; }
    set { testString = value; }
}
<TextBlock
    Text="{Binding Path=TestString, Mode=TwoWay}"
    Foreground="Red"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontFamily="Calibri"
    FontSize="24"
    FontWeight="Bold">
</TextBlock>
public string TestString;
public string TestString { get; set; }
private string testString;

public string TestString
{
    get { return testString; }
    set {
        if (testString != value) {
            testString = value;
            RaisePropertyChanged("TestString");
        }
    }
}

public event PropertyChangedEventHandler PropertyChanged;

private void RaisePropertyChanged(string propertyName)
{
    if (PropertyChanged != null) {
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

我很惊讶地看到,由于没有实现接口,性能降低了4倍。

你说的是真的。最后我就这么做了,但在此之前,我已经浪费了好几个小时的时间,我的头撞在墙上,试图了解到底发生了什么。我只是不明白为什么getter/setter的存在与否会将某些内容从字段更改为属性。我想这是编译器在编译时所做的事情。谢谢你的关注@Silva这样做是因为您使用的是字段的语法。C#语言是这样构造的,以区分属性声明和字段声明。@Silva:与其以后“花几个小时把头撞在墙上”,不如使用输出窗口调试绑定错误。而且,快速的谷歌搜索会让你