Create an event to watch for a change of variable - c#

Let's just say that I have:
public Boolean booleanValue;
public bool someMethod(string value)
{
// Do some work in here.
return booleanValue = true;
}
How can I create an event handler that fires up when the booleanValue has changed? Is it possible?

Avoid using public fields as a rule in general. Try to keep them private as much as you can. Then, you can use a wrapper property firing your event. See the example:
class Foo
{
Boolean _booleanValue;
public bool BooleanValue
{
get { return _booleanValue; }
set
{
_booleanValue = value;
if (ValueChanged != null) ValueChanged(value);
}
}
public event ValueChangedEventHandler ValueChanged;
}
delegate void ValueChangedEventHandler(bool value);
That is one simple, "native" way to achieve what you need. There are other ways, even offered by the .NET Framework, but the above approach is just an example.

INotifyPropertyChanged is already defined to notify if property is changed.
Wrap your variable in property and use INotifyPropertyChanged interface.

Change the access of the BooleanValue to private and only allow changing it through one method for consistency.
Fire your custom event in that method
.
private bool _boolValue;
public void ChangeValue(bool value)
{
_boolValue = value;
// Fire your event here
}
Option 2: Make it a property and fire the event in the setter
public bool BoolValue { get { ... } set { _boolValue = value; //Fire Event } }
Edit: As others have said INotifyPropertyChanged is the .NET standard way to do this.

Perhaps take a look at the INotifyPropertyChanged interface. You're bound to come across it's use again in future:
MSDN: http://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged.aspx

CallingClass.BoolChangeEvent += new Action<bool>(AddressOfFunction);
In your class with the bool property procedure:
public event Action<bool> BoolChangeEvent;
public Boolean booleanValue;
public bool someMethod(string value)
{
// Raise event to signify the bool value has been set.
BoolChangeEvent(value);
// Do some work in here.
booleanValue = true;
return booleanValue;
}

No it is not possible* to get notified about for changes in value of a variable.
You can achieve almost what you want by making the value to be a property of some class and fire events on change as you wish.
*) if your code is debugger for a process you can make CPU to notify you about changes - see data chage breakpoints in Visual Studio. This will require at least some amount of native code and harder to implement correctly for manged code due to hance of objects to be moved in memory by GC.

Related

how to provide change notification for a property when a subproperty changes?

This is such a basic question, but I don't think I've done this before despite having bound so many properties. I originally was planning to bind a class called TimeScale to various objects.
In class A we have a dependency property that I want to call change notification on. However, change notification is not done manually through this class.
public TimeScale AxisTimeScale
{
get { return (TimeScale)GetValue(AxisTimeScaleProperty); }
set { SetValue(AxisTimeScaleProperty, value); }
}
public static readonly DependencyProperty AxisTimeScaleProperty =
DependencyProperty.Register("AxisTimeScale",
typeof(TimeScale), typeof(SignalPanel),
new FrameworkPropertyMetadata(new TimeScale()));
this binds to source class B
private class B
{
private TimeScale _GraphTimeScale;
public TimeScale GraphTimeScale
{
get { return _GraphTimeScale; }
set
{
if (value != _GraphTimeScale)
{
_GraphTimeScale = value;
OnPropertyChanged("GraphTimeScale");
}
}
}
}
Looking at it again I guess all I really want is to call propertychanged on a dependency property, but since I didn't implement Inotifypropertychanged, I am wondering how i do that.
I think DependencyObject already implements Inotifypropertychanged, so I have access to this:
OnPropertyChanged(new DependencyPropertyChangedEventArgs(property, old value, new value));
However, inserting the same object into both the old value and new value slots results in the PropertyChanged event not firing (I assume the implementation checks whether the two values are the same before firing the event). I want to avoid creating a new object if possible. I guess one option is to override OnPropertyChanged. Nope that also requires me to have a dependency propertychanged event args.
Update
OnPropertyChanged("TimeScale");
to
OnPropertyChanged("GraphTimeScale");
Or,
you can wrap the TimeScale class with an ObservableObject so that you can subscribe to object change events and raise them from there.
More info: http://msdn.microsoft.com/en-us/library/ff653818.aspx
Subscribe to the PropertyChanged notification of NumberOfUnits, and then raise OnPropertyChanged("GraphTimeScale") in the property changed event handler.
Would be interested if there is a better way though.

what is the use of custom event arg?

Here is the code for custom event args. I am confuse about use of those and also role of those. I can not understand this property public object AddedObject { get; private set; } the code is here :
public class ObjectAddedEventArgs : EventArgs
{
public ObjectAddedEventArgs(object addedObject)
{
AddedObject = addedObject;
}
public object AddedObject { get; private set; }
}
I can not understand use of the get and set property of added object. Please explain to me.
The AddedObject property is what is called an "auto property", which simply means that the C# compiler will generate a private variable to hold the value of the property. The "get" is the mechanism which allows you to read the value of the property. The "set" is the mechanism which allows you to set the value of the property, although in this case since the set is private you aren't able to set the value. This translates to code which would look roughly like this:
private object _AddedObject;
public object AddedObject
{
get { return this._AddedObject; }
private set { this._AddedObject = value; }
}
The class itself (the ObjectAddedEventArgs class) is used to provide additional data (the AddedObject value) to an event handler which, presumably, would access that data and do something with it as part of it's response to the event.
As per Microsoft's documentation:
EventArgs is the base class for classes containing event data.
....
This class contains no event data; it is used by events that do not
pass state information to an event handler when an event is raised. If
the event handler requires state information, the application must
derive a class from this class to hold the data.
That being said, the original developer of that class intended to handle events and at the same time making the object AddedObject available to the event handler method. See the website above for a nice example.
the good thing when you declare your events like this
event EventHandler<ObjectAddedEventArgs> MyObjectAddedEvent;
you can subscribe to it in a weak manner easily
myObjectInstance.MyObjectAddedEvent += new EventHandler<ObjectAddedEventArgs>(MyObjectAddedEventMethod).MakeWeak(eh => d.MyObjectAddedEvent -= eh);
private void MyObjectAddedEventMethod(object sender, ObjectAddedEventArgseventargs)
{
//do something with the event args
}
the weak stuff you find here.

Direct way for firing up some events when a boolean field changes?

I wonder if there is a way to directly control some events when a boolean field is changing from true to false?
something like using delegate?
Actually I have lots of user input controls (check box, text box and etc..) and I am looking for a way around the using of foreach and control.disabled stuff.
Properties are always good to fire up event from within:
private bool check = false;
public bool MyCheckboxChecked
{
get
{
return check;
}
set
{
if (check == true && value == false)
MyEvent("MyCheckboxChecked is about to change from true to false!");
check = value;
}
}
If you want to monitor public fields of controls (ie CheckBox.Checked), you can always hookup for events already provided by them like CheckedChanged.
Use a property to set the field value. Raise a PropertyChanged event in the setter of the property.
Sample code:
bool Flag
{
get { return this.flag; }
set
{
if (this.flag != value)
{
this.flag = value;
// Raise PropertyChanged event here ..
}
}
}
That's right. If you are using WPF, you can implement INotifyPropertyChanged interface and Binding which is very convenient for you need.
Or use action:
private bool isIt;
public Action YourAction{get; set;}
public bool IsIt
{
get{return isIt;}
set{isIt = value; if(YourAction != null) YourAction();}
}
Sure there is, use an event raiser on the set accessor of a property instead of changing directly the member variable...

c# bool.change event

Can I setup an event listener so that when a bool changes a function is called?
You should use properties in C#, then you can add any handling you want in the setter (logging, triggering an event, ...)
private Boolean _boolValue
public Boolean BoolValue
{
get { return _boolValue; }
set
{
_boolValue = value;
// trigger event (you could even compare the new value to
// the old one and trigger it when the value really changed)
}
}
Manually, Yes you can
public delegate void SomeBoolChangedEvent();
public event SomeBoolChangedEvent SomeBoolChanged;
private bool someBool;
public bool SomeBool
{
get
{
return someBool;
}
set
{
someBool = value;
if (SomeBoolChanged != null)
{
SomeBoolChanged();
}
}
}
Not sure however if this is what you are looking for.
The important question here is: when a bool what changes?
Since bool is a value type you cannot pass around references to it directly. So it doesn't make sense to talk about anything like a Changed event on bool itself -- if a bool changes, it is replaced by another bool, not modified.
The picture changes if we 're talking about a bool field or property on a reference type. In this case, the accepted practice is to expose the bool as a property (public fields are frowned upon) and use the INotifyPropertyChanged.PropertyChanged event to raise the "changed" notification.
Look into implementing INotifyPropertyChanged. MSDN has got a great How To on the subject

C# Fastest way to know something in object has changed?

I want to know, if the value of any of the private or public fields has changed.
Is there any way other than over-riding GetHashCode() or calculating CRC?
The algorithm should be fast too.
Normally, this would be done with the INotifyPropertyChanged interface (link). It is really only practical to use it with properties, though, not fields. However, you could create a private property for each of your private fields. Once you have everything as a property, edit the setter so that you check if the value has changed, then call NotifyPropertyChanged() if it has.
Example:
public event PropertyChangedEventHandler PropertyChanged;
private int _foo;
public int Foo
{
get { return _foo; }
set
{
if (_foo != value)
{
_foo = value;
NotifyPropertyChanged("Foo");
}
}
}
private void NotifyPropertyChanged(string info)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
You may want to encapsulate all your data (which you want to monitor for change) inside the get/set accessors (a.k.a. properties).
Then, in set accessor, check if value has changed, set it to new value, and:
set _dirty to true (if you need to check it later)
or
raise some event to your liking
Some notes on CRC - even if you have non-colliding CRC/HASH algoritam for your object, you must have original hash somewhere. But simple hashes are likely to duplicate, so you again have speed issue.
If it needs to work for any type and needs to detect any modification, with no false negatives or false positives, I don't see any better way than a copy of all field values for reference. Since you need it to be fast, I would recommend the following:
Write a routine that uses reflection to perform a shallow copy of all field values.
Write a routine that compares the fields by value (if you're looking for changes in nested structures, like arrays or collections, your problem is much tougher.)
Once the above work, you can use IL Emit and write code that does the Reflection once and emits code for the shallow-copy and comparison operations. Now you have some DynamicMethod instances you can use for each operation. These are quite fast, once emitted and jitted.
Insert in every public setter a boolean value, like m_IsChanged, then using a public getter only to check if one of the properties has been changed.
Example:
private bool m_IsChanged = false;
private double m_DoubleValue;
//[...] all other private properties
public double DoubleValue
{
get { return m_DoubleValue; }
set
{
if(m_DoubleValue != value)
m_IsChanged = true;
m_DoubleValue = value;
}
}
//[...] all other getters/setters
public bool IsChanged
{
get { return m_IsChanged; }
}

Categories

Resources