How to fire RaisePropertyChanged from within a setter - c#

I have a property defined with no explicit mention of backing field in a way like this :
//How to fire RaisePropertyChanged("Name") from setter
public string Name { get; set; }
How exactly do I fire a RaisePropertyChanged event in the setter of this property ?
I know how to do it when there is a private backing field and with a public property encapsulating it.
Is a multi line setter allowed in this scenario ?

No, you can't do this with an automatic property. You'll need to have a backing field and define both the getter and setter yourself, and raise the event in the setter as you described.

That's an Automatic Property, you need to have a backing field.
private string _name;
public string Name
{
get { return name; }
set
{
name = value;
RaisePropertyChanged("Name");
}
}

Related

C# Is there a reason to avoid reassigning value in property setter?

This is the pattern I see everywhere in "legacy" code, but now no one knows why it originated:
public virtual ICollection<SomeClass> SomeProperty
{
get { return m_SomeProperty; }
set
{
if (m_SomeProperty == value)
return;
m_SomeProperty = value;
}
}
My question is, what is the benefit of the "if" check, if any? Can it be simplified to usual
public virtual ICollection<SomeClass> SomeProperty
{
get { return m_SomeProperty; }
set { m_SomeProperty = value; }
}
without any side effects?
Doesn't make much sense if the class doesn't implement INotifyPropertyChanged
But if, you should only fire the PropertyChanged event if a property was changed and not if the same value was assigned. The link contains an example.
If the m_SomeProperty is a private field, this is meaningless. Much better to use auto-property instead:
public virtual ICollection<SomeClass> SomeProperty { get; set; }
In this case, all occurrences of m_SomeProperty should be replaced with SomeProperty.
Side effects are possible if the m_SomeProperty is a property itself. In this case it can have its own setter which should not be triggered if its new value is the same.

Property Getters and Setters when implementing INotifyPropertyChanged?

I am trying to implement INotifyPropertyChanged for a lot of classes, and each of these classes have lots and lots of properties. I have been following this MSDN documentation for how to implement INofifyPropertyChanged, but their instructions don't seem to be practical in cases where a class has many many properties.
Currently most of my properties use the short hand:
public DateTime? DateClosed { get; set; }
But the documentation says that i need to add the following to each setter method:
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("DateClosed");
This means that I then need to declare a body for the get method and declare private variables to handle the actual getting and setting of properties. Like this:
private DateTime? _dateOfIncident = null;
public DateTime? DateClosed
{
get { return _dateOfIncident; }
set
{
_dateOfIncident= value;
// Call OnPropertyChanged whenever the property is updated
OnPropertyChanged("DateClosed");
}
}
Does anyone know a way around this?
A few classes can easily be changed to implement INotifyPropertyChanged. But since you state you have a lot of classes with a lot of properties, it's a real burden to get this done manually or even with templates.
What you really need is a tool that does it for you, so I present you Fody and it's NotifyPropertyChanged plugin. What Fody does is weave some extra code in between your code at compile time. The only thing you have to do is add a single attribute on the classes you want to implement INotifyPropertyChanged and the rest is done for you.
[ImplementPropertyChanged]
public class Person
{
public string GivenNames { get; set; }
public string FamilyName { get; set; }
public string FullName
{
get
{
return string.Format("{0} {1}", GivenNames, FamilyName);
}
}
}
I'm not sure you're going to find a workaround here. Auto-properties, as you're using them now, are really just a compiler shorthand that get's converted to full properties with a backing field eventually anyway (at least, as I understand it).
The use of INPC is a routine that's sorta separate and apart from the duty of a normal property. It's notifying subscribers (usually, your view XAML) that the property in question has changed or is changing.
tl;dr -- you're not going to get around having to rewrite autoproperties to full properties with backing fields. But toolkits like MVVMLight have some great Visual Studio code snippets to make this relatively fast. Eventually you can even do this:
private string _someString;
public string SomeString
{
get { return _someString;}
set
{
//Set returns bool, so you can trigger other logic on it!
Set(() => SomeString, ref _someString, value);
}
}
This gives you some neat features:
Strong naming (unlike the magic string in your example)
Set only triggers INPC event if the value is different
Set returns boolean so you can perform more action if the value changed
MVVMLight is nice in that you don't have to use all its features, or even implement MVVM pattern. It just has a lot of nice 'tools' you can leverage.
There are a lot of patterns to do it, or you can buy a tool like PostSharp that will do it for you.
For example, here is one method of doing it:
public abstract class BaseNotifyPropertyChanged : INotifyPropertyChanged
{
private Dictionary<string, object> _valueStore = new Dictionary<string, object>();
public event PropertyChangedEventHandler PropertyChanged;
protected T Get<T>([CallerMemberName]string property = null)
{
object value = null;
if (!_valueStore.TryGetValue(property, out value))
return default(T);
return (T)value;
}
protected void Set<T>(T value, [CallerMemberName]string property = null)
{
_valueStore[property] = value;
OnPropertyChangedInternal(property);
}
protected void OnPropertyChanged([CallerMemberName]string property = null)
{
OnPropertyChangedInternal(property);
}
private void OnPropertyChangedInternal(string propertyName)
{
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
Which you then inherit from your classes:
public class PlainOldObject : BaseNotifyPropertyChanged
{
public int MyProperty
{
get { return Get<int>(); }
set { Set(value); }
}
}
Which takes care of the backing store and everything for you. You may want to add logic to only call the OnPropertyChangedInternal if the property actually changed (compare references or value), but I'll leave that as an exercise for you.
Simply use the Observable Object class. Instead of creating a DateTime property, you'd create an ObservableObject<DateTime> and you would just bind to DateClosed.Value.

How I can bind property, which use another static property

I use mvvm pattern in my progeсt (C#), and I have some problem.
I have a label on my view, and label's text is binded to property from my viewModel:
val label=new Label();
label.SetBinding<StatusViewModel>(Label.TextProperty, x=>x.TextProp);
this is my view model, which implements INotifyPropertyChanged interface:
class StatusViewModel
{
private string _textProp;
public string TextProp
{
get
{
return _textProp;
}
set
{
if(_textProp == value)
return _textProp;
_textProp=value;
OnPropertyChange();
}
}
}
but I have another static property:
static class StaticClass
{
public static string StaticText {get; set; }
}
And I want use this static property StaticText inside my TextProp property from StatusViewModel. And StaticText property mast notify label about it changes.
P.S. sorry about possible mistakes, I typed this code from my head.
If you are binding to static properties, you are probably doing it wrong :)
That said, the initial bind is super easy. You just need to add a property that returns the static one:
public string StaticTextRedirect
{
get { return StaticClass.StaticText; }
set { StaticClass.StaticText = value; }
}
The PropertyChanged event is another beast. You could raise it from the StaticTextRedirect property of course, but that won't fire if some other class changes the property. You'll probably need to just raise a custom event in the static property's setter that client code can listen to and raise the appropriate PropertyChanged event for.

When to use the public or private property?

If I have a class like so:
public class MyClass:INotifyPropertyChanged
{
private Visibility isVisible;
private ObservableCollection<string> names;
public Visibility IsVisible
{
get{ return isVisible;}
set { isVisible = value; OnPropertyChanged("IsVisible");}
}
public ObservableCollection<string> Names
{
get { return names;}
set { names = value; OnPropertyChanged("Names");}
}
//ctor
public MyClass(){
names = new ObservableCollection<string>();
}
//INotifyPropertyChanged implementation
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Before any one beheads me - I have done quite a bit of looking up and have found a mixed bag of answers...
Do I modify the public or private properties/variables for use in my bindings? i.e. I have an issue where adding to names collection will trigger OnPropertyChanged and changing isVisible will NOT trigger OnPropertyChanged. My assumption is that this is because names is an ObservableCollection where as isVisible is not but I am not sure...
If I am supposed to uses the public properties - what is the need for having the private ones?
You don't need a private property, only a private field would be enough so replace:
private Visibility isVisible {get; set;}
with
private Visibility isVisible;
If I am supposed to uses the public properties - what is the need for
having the private ones?
You cannot use Auto-properties with INotifyPropertyChanged. That is why you need a backing field for your property IsVisible.
See: An elegant way to implement INotifyPropertyChanged
So I think you are confusing Properties and Fields (aka variables).
public class Example()
{
public int FieldExample;
private int _propertyExample;
public int PropertyExample
{
get
{
return _propertyExample;
}
set
{
_propertyExample = value;
}
}
}
In simple usage scenarios, the difference between a field and a property isn't obvious. But properties have different plumbing under the hood that allows them to take advantage of reflection and binding. For WPF, this means you've got to have public properties. Best practice for a Public Property is associate it with a private (or protected) field - and that field name is usually either prefixed with an _ and/or starts with lower case character. This is called a "backing field."
The private backing field holds the actual data, the public property is just the means by which other classes can interact with that data. Inside the get and set blocks, you can place any code you want: instead of returning my backing field, I could instead put: return 5;. It's not useful, and it's poor practice, but I can. Generally, the code that resides in your get and set blocks should still set or get the value; although you might validate the input first, and/or format it first. The pattern you are implementing in your sets for WPF raises an event that the property has changed. Other parts of your program are listening for that event so they know to update the UI.
So in your code, if you only change the backing field and don't raise an event that there has been a change, the UI will not update. You might desire this behavior if you are performing a complex action on an object, and want to hold off performing an UI update until a complete batch of items are finished, but that's an optimization and for starters you are probably better off always accessing/setting to the Public Property.

Howcome the get/set in dependency property doesn't do anything?

I've created a dependency property like this:
public partial class MyControl: UserControl
{
//...
public static DependencyProperty XyzProperty = DependencyProperty.Register("Xyz",typeof (string),typeof (MyControl),new PropertyMetadata(default(string)));
public string Xyz
{
get { return (string) GetValue(XyzProperty ); }
set { SetValue(XyzProperty , value); }
}
//...
}
Then bind it to my wpf window and everything worked fine.
When I tried to add some logic to the setter I notice it wasn't being called. I modify the get;Set up to a point now they look like this:
get{return null;}
set{}
And it is still works! How come? What's the use of that GetValue/SetValue calls?
The WPF data binding infrastructure uses the DependencyProperty directly, the Xyz property is a convenience interface for the programmer.
Take a look at the PropertyMetadata in the call to DependencyProperty.Register, you can supply a callback that will run when the property value is changed, this is where you can apply your business logic.
The DependencyProperty is the backing store for the XyzProperty. If you access the property through the DependencyProperty interface, it completely bypasses the Property's Get/Set accessor.
Think of it this way:
private int _myValue = 0;
public int MyValue
{
get { return _myValue; }
set { _myValue = value; }
}
In this instance, if I manually assign _myValue = 12, obviously the "Set" accessor for the MyValue property won't be called; I completely bypassed it! The same is true for DependencyProperties. WPF's binding system uses the DependencyProperty interfaces directly.

Categories

Resources