INotifyPropertyChanged best practices - inotifypropertychanged

When I have a class that implements INotifyPropertyChanged, is it ok to expose the implementation as a public method?
For instance, if I have a property called "Sum" on a class, and I want a button click in the UI to update the sum, what is the best way to do this?
Below is some pseudo-code to illustrate what I mean
classinstance.NotifyPropertyChanged("Sum");
...
public Sum {
get { return x + y + z; }
}

In .Net the preferred practice for methods that raise events is for the method to be declared as protected so that it can only be called by derived classes (This is because only the class that declares the event can raise it. In order to raise the event from a derived class a method is required to raise the event).
For example...
protected void OnPropertyChanged(string propertyName)
{
var handler = this.PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
This method is then called by the class (or derived classes) in a property setter to indicate that a property has changed, like so...
public object MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
OnPropertyChanged("MyProperty");
}
}
Other objects can then subscribe to this event and will be notified every time the MyProperty property is changed.
Now, to answer your question as to whether the OnPropertyChanged method can be public. The answer is yes but you should be asking yourself why this would be the case.
Why would another class know when a property has changed so that it can call the method? if it already 'knows' when the property has changed then you shouldn't need to subscribe to the property changed event in the first place! Only the class itself should 'know' when one of its own properties has changed.
In your example You are notifying that the property 'sum' has been changed. but it hasn't. In fact, your code doesn't even allow that property to be changed outside of its own class.
I suspect that maybe you want some way of notifying that the sum property needs to be re-evaluated because a dependent property has been changed. If this is the case then you need to raise a property changed event when that dependent property changes.
Imagine that changes to the 'MyProperty' property shown earlier also means that 'Sum' has changed then that would be handled like this:
// This property is used by the 'sum' property so if this changes
// clients need to know that 'sum' has also changed.
public object MyProperty
{
get { return _myProperty; }
set
{
_myProperty = value;
OnPropertyChanged("MyProperty");
OnPropertyChanged("Sum");
}
}

as for much more pretty to implement base :
public abstract class NotificationObject : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged<T>(Expression<Func<T>> me)
=> RaisePropertyChanged((me.Body as MemberExpression)?.Member.Name);
protected virtual void RaisePropertyChanged(string propertyName)
=> PropertyChanged?.Invoke(this, propertyName);
}
It's also worthy to lookup for https://msdn.microsoft.com/en-us/magazine/mt736453.aspx

Related

Is there a possibility to control the Expando class to not allow adding properties/members under certain conditions?

As far as I can tell, the Expando class in Kephas allows adding new members on the fly. Unlike the ExpandoObject in .NET, I noticed it is not sealed, so I could change its behavior, but I don't really know how.
[EDITED]
My scenario is to make the expando readonly at a certain time.
Try this snippet:
public class ReadOnlyExpando : Expando
{
private bool isReadOnly;
public ReadOnlyExpando()
{
}
public ReadOnlyExpando(IDictionary<string, object> dictionary)
: base(dictionary)
{
}
public void MakeReadOnly()
{
this.isReadOnly = true;
}
protected override bool TrySetValue(string key, object value)
{
if (this.isReadOnly)
{
throw new InvalidOperationException("This object is read only").
}
return base.TrySetValue(key, value);
}
}
For other scenarios you may want to check the LazyExpando class, which provides a way to resolve dynamic values based on a function, also handling circular references exception.

Object obtained from WCF service has null private fields, even though they are initialized in the class [duplicate]

I need to initialize private readonly field after Deserialization. I have folowing DataContract:
[DataContract]
public class Item
{
public Item()
{
// Constructor not called at Deserialization
// because of FormatterServices.GetUninitializedObject is used
// so field will not be initialized by constructor at Deserialization
_privateReadonlyField = new object();
}
// Initialization will not be called at Deserialization (same reason as for constructor)
private readonly object _privateReadonlyField = new object();
[DataMember]
public string SomeSerializableProperty { get; set; }
[OnDeserializing]
public void OnDeserializing(StreamingContext context)
{
// With this line code even not compiles, since readonly fields can be initialized only in constructor
_privateReadonlyField = new object();
}
}
All what I need, that after Deserialization _privateReadonlyField is not null.
Any suggestions about this - is it possible at all?
Or I need to remove "readonly" key, which is not a good option.
Serialization is able to read in values for read-only fields because it uses reflection, which ignores accessibility rules. It can be argued that the following is, therefore, justified as part of the serialization process, even though I would recommend strongly against it in almost any other circumstance:
private readonly Doodad _oldField;
[OptionalField(VersionAdded = 2)]
private readonly Widget _newField;
[OnDeserialized]
private void OnDeserialized(StreamingContext context)
{
if (_oldField != null && _newField == null)
{
var field = GetType().GetField("_newField",
System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.DeclaredOnly |
System.Reflection.BindingFlags.NonPublic);
field.SetValue(this, new Widget(_oldField));
}
}
Any field declared as private readonly can be instantiated in the same line where it was declared or inside a constructor. Once that is done it cannot be changed.
From MSDN:
The readonly keyword is a modifier that you can use on fields. When a field declaration includes a readonly modifier, assignments to the fields introduced by the declaration can only occur as part of the declaration or in a constructor in the same class.
That means that you will have to remove readonly keyword to get it to work.

How can I catch an event of an Object inside a ComboBox?

So basically I have a ComboBox on a form, which I populated by adding custom object named "Category" and by setting the DisplayMember to the property "Name" of my object.
On another form that can be opened at the same time, I can edit the name of theses "Category" objects. I raise an Event, "NameChanged" but how can I catch it on the form which contains the ComboBox ?
Even if the property "Name" of the object "Category" change, the display on the ComboBox doesn't autoupdate. So I need to catch the event, but I don't know how to do it.
Thanks to anyone who can help me.
If you make your Category class implement INotifyPropertyChanged, you can handle events when a property changes.
To do so, you have to change your property from a simple property:
// will NOT raise event
public string Name { get; set; }
to something more like:
// will raise event
public string Name
{
get { return _Name; }
set
{
if (_Name != value)
{
_Name = value;
OnPropertyChanged("Name");
}
}
}
private string _Name;
and then implement INotifyPropertyChanged in your class as well:
public event EventHandler<PropertyChangedEventArgs> PropertyChanged;
protected virtual void OnPropertyChanged(PropertyChangedEventArgs e)
{
if (PropertyChanged != null)
PropertyChanged(this, e);
}
protected virtual void OnPropertyChanged(string propertyName)
{
OnPropertyChanged(new PropertyChangedEventArgs(propertyName));
}
Now, when adding a Category object to your ComboBox, subscribe to the PropertyChanged event which will be raised every time the Name property changes.
An Even Better Way
Consider using the Binding class to populate your ComboBox. Binding automagically uses INotifyPropertyChanged to update the display when a property value changes.

RIA, Silverlight 4, EntityStates and Complex Types

I've got a RIA silverlight 4 app with a complex data type as a model. As a familiar example let's call it aspnet_User which has a member object called aspnet_Membership; aspnet_User has a member called "UserName" and aspnet_Membership has a member called "Email". Now using the aspnet_User as a datacontext I want to bind to any changes in aspnet_User or an attached aspnet_Membership - i.e. I want to show if an aspnet_User is 'dirty'. The dirty flag should show if I change either aspnet_User.UserName or aspnet_Membership.Email. Now previously I have implemented a Converter and bound to the EntityState on an object, and this is fine for showing whether simple properties are dirty but EntityState is not altered when aspects of aspnet_Membership member are edited.
I have tried to implement a property called BubbledEntityState which reflects a modified EntityState on either aspnet_User or aspnet_membership. It is defined in a partial class in the Silverlight project. This needs to react to EntityState PropertyChanged events on aspnet_User or it's member aspnet_Membership. So I've tried to handle these events in the partial OnCreated method. Strangely however this isn't getting called at all. Here is the method:
public partial class aspnet_User
{
partial void OnCreated()
{
this.aspnet_Membership.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(aspnet_Membership_PropertyChanged);
this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(aspnet_User_PropertyChanged);
}
...
}
I'm presuming aspnet_User objects are constructed on the server and are not 'reconstructed' when they are reconstituted on the client after RIA has done it's WCF call. This strikes me as peculiar. Am I doing something cranky? Anyone got a better way of dealing with this?
OK I've got this working. It still seems a bit convoluted, but rather than using the OnCreated partial method I've overloaded the OnLoaded method:
protected override void OnLoaded(bool isInitialLoad)
{
base.OnLoaded(isInitialLoad);
this.PropertyChanged += new System.ComponentModel.PropertyChangedEventHandler(aspnet_User_PropertyChanged);
}
partial void OnCreated()
{
}
void aspnet_User_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "aspnet_Membership")
{
if (this.aspnet_Membership != null)
{
this.aspnet_Membership.PropertyChanged+=new System.ComponentModel.PropertyChangedEventHandler(aspnet_Membership_PropertyChanged);
}
}
if (e.PropertyName == "EntityState")
this.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("BubbledEntityState"));
}
void aspnet_Membership_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (e.PropertyName == "EntityState")
this.OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("BubbledEntityState"));
}
public EntityState BubbledEntityState
{
get
{
if (this.EntityState== System.Windows.Ria.EntityState.Unmodified)
{
if (this.aspnet_Membership==null)
return System.Windows.Ria.EntityState.Unmodified;
if (this.aspnet_Membership.EntityState== System.Windows.Ria.EntityState.Modified)
return System.Windows.Ria.EntityState.Modified;
return System.Windows.Ria.EntityState.Unmodified;
}
return this.EntityState;
}
}

IDisposable base class which owns managed disposable resource, what to do in subclasses?

I have a base class that owns a managed disposable resource (.NET PerformanceCounter). I understand about implementing IDisposable on the class so that I can explicitly call Dispose on the resource. From the examples I have seen, people typically use a private boolean member variable "disposed" and set it to true inside of Dispose. Later, if there is an attempt to access a public method or property, an ObjectDisposedException is raised if "disposed" is true.
What about in the subclasses? How would the subclasses, in their public methods and properties, know that that they had been disposed? At first I thought that the subclasses would not have to anything special (like implement their own version of Dispose) since the thing that needs to be disposed is only in the base class (let's assume that the subclasses won't be adding any data that needs to be explicitly disposed) and the base class' Dispose should handle that. Should the subclasses override the base class' virtual Dispose method solely for the purpose of setting its own "disposed" member variable?
Here is a very stripped-down version of the class hierarchy in question.
class BaseCounter : IBaseCounter, IDisposable
{
protected System.Diagnostics.PerformanceCounter pc;
private bool disposed;
public BaseCounter(string name)
{
disposed = false;
pc = CreatePerformanceCounter(name);
}
#region IBaseCounter
public string Name
{
get
{
if (disposed) throw new ObjectDisposedException("object has been disposed");
return pc.CounterName;
}
}
public string InstanceName
{
get
{
if (disposed) throw new ObjectDisposedException("object has been disposed");
return pc.InstanceName;
}
}
#endregion IBaseCounter
#region IDisposable
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
if (pc != null)
{
pc.Dispose();
}
pc = null;
disposed = true;
}
}
}
public void Dispose()
{
Dispose(true);
}
#endregion IDisposable
}
class ReadableCounter : BaseCounter, IReadableCounter //my own interface
{
public ReadableCounter(string name)
: base(name)
{
}
#region IReadableCounter
public Int64 CounterValue()
{
return pc.RawValue;
}
#endregion IReadableCounter
}
class WritableCounter : BaseCounter, IWritableCounter
{
public WritableCounter(string name)
: base(name)
{
}
#region IWritableCounter
public Increment()
{
pc.Increment();
}
#endregion IWritableCounter
}
In our system, ReadableCounter and WritableCounter are the only subclasses of BaseCounter and they are only subclassed to one more level via a code generation processes. The additional subclassing level only addes a specific name so that it becomes possible to create objects that correspond directly to named counters (e.g. if there is a counter that is used to count the number of widgets produced, it ends up being encapsulated in a WidgetCounter class. WidgetCounter contains the knowledge (really, just the counter name as a string) to allow the "WidgetCounter" performance counter to be created.
Only the code-generated classes are used directly by developers, so we would have something like this:
class WritableWidgetCounter : WritableCounter
{
public WritableWidgetCounter
: base ("WidgetCounter")
{
}
}
class ReadableWidgetCounter : ReadableCounter
{
public ReadableWidgetCounter
: base ("WidgetCounter")
{
}
}
So, you see that the base class owns and manages the PerformanceCounter object (which is disposable) while the subclasses use the PerformanceCounter.
If I have code like this:
IWritableCounter wc = new WritableWidgetCounter();
wc.Increment();
wc.Dispose();
wc.Increment();
wc = null;
How could WritableCounter know, in Increment, that it had been disposed? Should ReadableCoutner and WritableCounter simply override the BaseCounter's
protected virtual void Dispose(bool disposing)
something like this:
protected virtual void Dispose(bool disposing)
{
disposed = true; //Nothing to dispose, simply remember being disposed
base.Dispose(disposing); //delegate to base
}
simply to set a ReadableCounter/WritableCounter-level "disposed" member variable?
How about if the base class (BaseCounter) declared disposed as protected (or made it a protected property)? That way, the subclasses could refer to it rather than adding a Dispose method simply for the purpose of remembering that Dispose had happened.
Am I missing the boat on this?
I have seen some disposable classes with a public IsDisposed property. You could do that and check it in your sub-classes.
Another thing I've done is a generic protected 'Validate' method that all sub-class methods call (and could override). If it returns, all is well, otherwise it might throw. That would insulate your sub-classes from the disposable innards altogether.
I have snippets that I use for implementing IDisposable, both in the base class and in the subclasses. You'd probably want the one for the subclass.
I swiped most of this code from MSDN, I think.
Here's the code for the base class IDisposable (not the one you want):
#region IDisposable Members
// Track whether Dispose has been called.
private bool _disposed = false;
// Implement IDisposable.
// Do not make this method virtual.
// A derived class should not be able to override this method.
public void Dispose()
{
Dispose(true);
// Take yourself off the Finalization queue
// to prevent finalization code for this object
// from executing a second time.
GC.SuppressFinalize(this);
}
// Dispose(bool disposing) executes in two distinct scenarios.
// If disposing equals true, the method has been called directly
// or indirectly by a user's code. Managed and unmanaged resources
// can be disposed.
// If disposing equals false, the method has been called by the
// runtime from inside the finalizer and you should not reference
// other objects. Only unmanaged resources can be disposed.
protected virtual void Dispose(bool disposing)
{
// Check to see if Dispose has already been called.
if (!this._disposed)
{
// If disposing equals true, dispose all managed
// and unmanaged resources.
if (disposing)
{
// TODO: Dispose managed resources.
}
// Release unmanaged resources. If disposing is false,
// only the following code is executed.
// TODO: Release unmanaged resources
// Note that this is not thread safe.
// Another thread could start disposing the object
// after the managed resources are disposed,
// but before the disposed flag is set to true.
// If thread safety is necessary, it must be
// implemented by the client.
}
_disposed = true;
}
// Use C# destructor syntax for finalization code.
// This destructor will run only if the Dispose method
// does not get called.
// It gives your base class the opportunity to finalize.
// Do not provide destructors in types derived from this class.
~Program()
{
// Do not re-create Dispose clean-up code here.
// Calling Dispose(false) is optimal in terms of
// readability and maintainability.
Dispose(false);
}
#endregion
And here's the code I use in the subclasses (this is the code you want):
#region IDisposable Members
// Track whether Dispose has been called.
private bool _disposed = false;
// Design pattern for a derived class.
// Note that this derived class inherently implements the
// IDisposable interface because it is implemented in the base class.
// This derived class does not have a Finalize method
// or a Dispose method without parameters because it inherits
// them from the base class.
protected override void Dispose(bool disposing)
{
if (!this.disposed)
{
try
{
if (disposing)
{
// Release the managed resources you added in
// this derived class here.
// TODO: Dispose managed resources.
}
// Release the native unmanaged resources you added
// in this derived class here.
// TODO: Release unmanaged resources.
_disposed = true;
}
finally
{
// Call Dispose on your base class.
base.Dispose(disposing);
}
}
}
#endregion
Look for the TODO: marks.