Binding question in WPF - Diference between Properties and Fields

断了今生、忘了曾经 提交于 2021-02-19 01:35:51

问题


I have a question about how bindings work in WPF.

If i have a viewmodel with a property like this:

private string testString;
public string TestString
{
    get { return testString; }
    set { testString = value; }
}

Then if I bind it to a xaml with something like this:

<TextBlock
    Text="{Binding Path=TestString, Mode=TwoWay}"
    Foreground="Red"
    HorizontalAlignment="Center"
    VerticalAlignment="Center"
    FontFamily="Calibri"
    FontSize="24"
    FontWeight="Bold">
</TextBlock>

It works... Nothing new here.

However, if I remove the getters and setters from the test string and end up with something like this:

public string TestString;

The very same binding doesn't work. I have no idea why this occurs because to me, it's equivalent a public attribute to a public attribute with custom get and set.

Can someone shed some light on this subject for me? :)

TYVM in advance!!

PS: Sorry about my syntax highlight. I just can't figure how to work with the code block.


回答1:


@Silva, your hunch is correct, there is something going on behind the scenes. I've only seen this addressed clearly in one blog post I've come across on Pete Brown's (Microsoft Developer Evangelist) blog:

http://10rem.net/blog/2010/12/17/puff-the-magic-poco-binding-and-inotifypropertychanged-in-wpf

Check out the section on where he writes about the PropertyDescriptor class. He also goes on to mention that it is relatively inefficient compared to using the more conventional method of implementing the INotifyPropertyChanged interface on the viewmodel class, like this:

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

I was pretty surprised to read that there's a 4x performance decrease by not implementing the interface.




回答2:


Removing the getter and setter changes the TestString member from being a property to being a field. This is why binding stops working and is probably not what you wanted to do (a public field like that is generally considered bad design).

You can let the compiler create the backing field automatically by declaring empty getter/setter, like this:

public string TestString { get; set; }



回答3:


I am not sure may be it has to do something with INotifyPropertyChanged, might be after removing Get Set it is not possible for WPF to identify whether source has been changed or not. Or it has been treated as Read Only property.

Request you to go through these article

http://msdn.microsoft.com/en-us/library/ms752347.aspx

http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx



来源:https://stackoverflow.com/questions/6318396/binding-question-in-wpf-diference-between-properties-and-fields

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!