I'm using delegates
in my c# windows forms application project.Using that I'm trying to remove items in a list box. I'm getting this null pointer exception and can somebody suggest a way to avoid that?
Delegate
public delegate void OrderEventDelegate (Object sender, OrderEventArgs args);
OrderEventArgs class
public class OrderEventArgs
{
private String message;
public String Message
{
get { return message; }
set { message = value; }
}
private int tableNo;
public int TableNo
{
get { return tableNo; }
set { tableNo = value; }
}
}
Class 1
public partial class Class1 : Form
{
private event OrderEventDelegate readyEvent;
public Class1(HomeForm parent, int tableNo)
{
InitializeComponent();
readyEvent -= new OrderEventDelegate(parent.readyOrder);
}
public void button_click()
{
OrderEventArgs readyOrderArg = new OrderEventArgs();
readyOrderArg.TableNo = 1;
readyOrderArg.Message = "123";
readyEvent(this, readyOrderArg);
}
}
Here readyEvent -= new OrderEventDelegate(parent.readyOrder);readyOrder() is the method which remove items in the list, which is located in the 'Homeform'.
Exception
It is possible to initialize C# events with an empty delegate. This way it can always be called safely without a null pointer check. As shown in this answer: https://stackoverflow.com/a/340618/2404788.
public delegate void OrderEventDelegate (Object sender, OrderEventArgs args) = delegate {};
If there's a possibility of something being null and you can do something about it/don't want to critically fail when it is, then check for it:
if (readyEvent != null) {
readyEvent( ... );
}
But the point here, I suppose, is that you don't want this thing to be null; so you should subscribe a handler to the event. I'm not sure why you're trying to remove a new instance of the delegate handler, but to add one you would use +=.
Related
I have a simple delegate, event and property allowing me to create callback subscriptions on events:
public static class Test
{
/// <summary>Delegate for property changed event</summary>
public delegate void TestEventHandler();
/// <summary>Event called when value is changed</summary>
public static event TestEventHandler OnTestHappening;
/// <summary>Property to specify our test is happening</summary>
private static bool testHappening;
public static bool TestHappening
{
get
{
return testHappening;
}
set
{
testHappening = value;
// Notify our value has changed only if True
// ie. Only fire an event when we're ready as we'll hook methods to the Event that must only fire if ready
if ( value )
{
if ( OnTestHappening != null )
OnTestHappening();
}
}
}
}
I can then easily subscribe and unsubscribe to the event and fire the event callbacks as needed:
public class Tester
{
private void Main()
{
Testing();
// Start the test
Test.TestHappening = true;
}
private void Testing()
{
// Unsubscribe from event
Test.OnTestHappening -= Testing;
// Check if we're busy testing yet
if ( !Test.TestHappening )
{
// Subscribe to event
Test.OnTestHappening += new Test.TestEventHandler( Testing );
return;
}
// Do stuff here....
}
}
When compiling, code analysis gives me, "CA1009: Declare event handlers correctly?" and I've searched high and low and found many questions, articles etc but none that feel like they address my scenario. I can't seem to find a concrete starting point for the conversion and I'm starting to wonder if I'm meant to completely rewrite the implementation?
Edit: Firstly I really appreciate the assists, I did look carefully through all the sites I could before posting this and I did see (and try work with) each of the links that you all posted. I even went back and studied delegates and events again but I feel like I'm missing the starting point somehow because each time I try change a part of it, I just keep producing errors that I can't come back from like:
public delegate void TestEventHandler( object sender, EventArgs e );
With the other links I visited, I could only find 1 similarity to my code (either in the delegate, the handler or the property) but couldn't find anything that related enough to mine to actually instil that "eureka" moment
Edit 2: I have now rebuilt my example with what "looks" to be the correct standard but this code is so fugly it looks like it was beaten with a confogulus stick and dipped in a tank of confutious before being deep fried in horriduculous:
public static class Test
{
/// <summary>Delegate for property changed event</summary>
public delegate void TestEventHandler( object sender, EventArgs e );
/// <summary>Event called when value is changed</summary>
public static event TestEventHandler OnTestHappening;
/// <summary>Property to specify our test is happening</summary>
private static bool testHappening;
public static bool TestHappening
{
get
{
return testHappening;
}
set
{
testHappening = value;
// Notify our value has changed only if True
// ie. Only fire an event when we're ready as we'll hook methods to the Event that must only fire if ready
if ( value )
{
if ( OnTestHappening != null )
OnTestHappening( null, EventArgs.Empty );
}
}
}
}
public class Tester
{
private void Main()
{
Testing( this, EventArgs.Empty );
// Start the test
Test.TestHappening = true;
}
private void Testing( object sender, EventArgs e )
{
// Unsubscribe from the event
Test.OnTestHappening -= Testing;
// Check if we're busy testing yet
if ( !GlobalClass.SystemOnline )
{
// Subscribe to the event
Test.OnTestHappening += new Test.TestEventHandler( Testing );
return;
}
// Do stuff here....
}
}
Please tell me I've missed something and that there is in fact a more elegant implementation
Edit 3 : Based on the code by Enigmativity, I've reworked the code to it's most basic form. I've also moved the code setting the variable to true in a different method so it doesn't look so daft sitting in Main.
public static class Test4
{
/// <summary>Event called when value is changed</summary>
public static event EventHandler TestHappening;
/// <summary>Property to specify our test is happening</summary>
private static bool test = false;
public static bool Test
{
get
{
return test;
}
set
{
// Notify our value has changed only if True
// ie. Only fire an event when we're ready as we'll hook methods to the Event that must only fire if ready
if ( value )
{
TestHappening( null, EventArgs.Empty );
}
}
}
}
public class Tester4
{
private void Main()
{
Testing( this, EventArgs.Empty );
}
private void Testing( object sender, EventArgs e )
{
// Unsubscribe from the event
Test4.TestHappening -= Testing;
// Check if we're busy testing yet
if ( !Test4.Test )
{
// Subscribe to the event
Test4.TestHappening += Testing;
return;
}
// Do stuff here....
}
private void SomeMethodCalledFromSomewhere()
{
// Set the value to true and thereby start the test
Test4.Test = true;
}
}
Would this be considered good code or should I rather have the OnTestHappening method as defined in Enigmativity's code?
Why can't I use a parameterless delegate? It's now using the default ( object sender, EventArgs e ) but that feels overkill and doesn't make sense why the compiler is happy with it but according to coding standards it's considered bad code? I'm not arguing the standard but rather trying to understand it's reasoning.
As per Storm's request, here is how I would most likely structure the code. It's more inline with the standard conventions.
public static class TestClass
{
public delegate void TestEventHandler(object sender, EventArgs e);
public static event TestEventHandler TestHappening;
private static bool test = false;
public static bool Test
{
get
{
return test;
}
set
{
test = value;
if (test)
{
OnTestHappening();
}
}
}
private static void OnTestHappening()
{
var handler = TestHappening;
if (handler != null)
handler(null, EventArgs.Empty);
}
}
And Tester would look like this:
public class Tester
{
public void Main()
{
TestClass.TestHappening += Testing;
Go();
}
private void Testing(object sender, EventArgs e)
{
Console.WriteLine(TestClass.Test);
TestClass.TestHappening -= Testing;
}
private void Go()
{
TestClass.Test = true;
}
}
Calling it would look like this:
var tester = new Tester();
tester.Main();
Running this outputs True to the console.
If I were writing this in a more standard way, it would look like this:
public class TestEventArg : EventArgs
{
public TestEventArg(bool updatedValue)
{
this.UpdatedValue = updatedValue;
}
public bool UpdatedValue { get; private set; }
}
public class TestClass
{
public event EventHandler<TestEventArg> TestHappening;
private bool test = false;
public bool Test
{
get { return test; }
set
{
var old = test;
test = value;
if (test != old)
OnTestHappening(test);
}
}
private void OnTestHappening(bool updatedValue)
{
var handler = TestHappening;
if (handler != null)
handler(this, new TestEventArg(updatedValue));
}
}
I was given a generic API class, that contains a custom event which always needs to be invoked by the main UI thread.
My job is to banish these invocation call from the custom class, to make it "painless".
It should be synchronized like the default events in WinForms (eg the Timer "Elapsed" event, which also needs no invocation when it published values to a text box)
Is it possible to solve this, since the custom class needs to know where to invoke?
Here's the (important part of the) code:
public class ContactSensorHelper
{
public event OnReleaseStateChanged ReleaseStateChanged;
public delegate void OnReleaseStateChanged(ContactSensorEventArgs e);
private ContactSensorEventArgs.ReleaseState recentReleaseState;
public void ReportStateChanged()
{
if (ReleaseStateChanged != null)
ReleaseStateChanged(new ContactSensorEventArgs()
{
State = recentReleaseState
});
}
public class ContactSensorEventArgs : EventArgs
{
//......
public ReleaseState State { get; set; }
//......
public enum ReleaseState
{
FullReleased,
PartlyReleased,
NotReleased
}
}
}
The call from main UI:
public void SensorInit()
{
//....
sensorHelper.ReleaseStateChanged += releaseStateChanged;
//....
}
private void releaseStateChanged(ContactSensorEventArgs e)
{
//example
textBox1.Text = e.State.ToString(); // Thread exception (obviously)
}
Does anybody have me a hint to start?
You could do this by using your own event calling, and storing a reference to the thread, when the event is attached.
With the event add/remove syntax, you can have the caller attach to the event like before, but internally you store a list, with a reference to the thread (using an AsyncOperation) and the delegate to be called (used a Tuple containing both in the example)
Below is an example. I tested it, and it worked as expected when testing, but you might have to add some locking of the list to make it thread safe in case events are added/removed simultaneously.
public class ContactSensorHelper:IDisposable
{
public delegate void OnReleaseStateChanged(ContactSensorEventArgs e);
private ContactSensorEventArgs.ReleaseState recentReleaseState;
public void ReportStateChanged()
{
if (statechangedList.Count > 0)
{
var e = new ContactSensorEventArgs()
{
State = recentReleaseState
};
statechangedList.ForEach(t =>
t.Item1.Post(o => t.Item2((ContactSensorEventArgs)o), e));
}
}
List<Tuple<AsyncOperation, OnReleaseStateChanged>> statechangedList = new List<Tuple<AsyncOperation,OnReleaseStateChanged>>();
public event OnReleaseStateChanged ReleaseStateChanged
{
add
{
var op = AsyncOperationManager.CreateOperation(null);
statechangedList.Add(Tuple.Create(op, value));
}
remove
{
var toremove = statechangedList.Where(t => t.Item2 == value).ToArray();
foreach (var t in toremove)
{
t.Item1.OperationCompleted();
statechangedList.Remove(t);
}
}
}
public void Dispose()
{
statechangedList.ForEach(t => t.Item1.OperationCompleted());
statechangedList.Clear();
}
public class ContactSensorEventArgs : EventArgs
{
//......
public ReleaseState State { get; set; }
//......
public enum ReleaseState
{
FullReleased,
PartlyReleased,
NotReleased
}
}
}
I declare a subscription to event in:
public class MainClass
{
public void btndel_bar_Click(object sender, RoutedEventArgs e)
{
SomeClass sc = new SomeClass();
sc.FieldUpdate += new SomeClass.FieldUpdateHandler(sc_FieldUpdate);
}
void sc_FieldUpdate(object sender, ValueEventArgs e)
{
MessageBox.Show(e.Smth_property);
}
}
And here is I want to listen event:
public class Someclass
{
public delegate void FieldUpdateHandler(object sender, ValueEventArgs e);
public event FieldUpdateHandler FieldUpdate;
void Somemethod()
{
string str = "Steel";
ValueEventArgs args = new ValueEventArgs(str);
FieldUpdate(this, args);
}
}
A class which carries data:
public class ValueEventArgs : EventArgs
{
private string smth;
public ValueEventArgs(string smth)
{
this.smth = smth;
}
public string Smth_property
{
get { return smth; }
}
}
I always have FieldUpdate=null. How to solve it?
You're calling Somemethod() in the constructor, before the calling code gets a chance to add the event handler.
Therefore, the event is still null.
The moment you create the object of SomeClass your event would get reinitialized.
Make your event a static so that multiple objects of SomeClass would share it
public static event FieldUpdateHandler FieldUpdate;
I've read articles about delegates and events and after reading I always I thought to make all operations again. I did all over again and it works! Consequently I done something wrong when I did at the beginning of.
After reading online tutorials regarding events , I think I almost have an idea of whats going on. I developed the following extremely simple code to trigger an event in case a value is greater than 5.I know the code is pretty useless but I am using it to get my point across. (Instead of a main I just used a button event to trigger the code.)
//declare the delegate
public delegate void MyDelegate(string str);
public class SomeClass
{
public event MyDelegate MyEventFromDelegate;
private int i;
public int I
{
get
{ return i; }
set
{
if (value > 5)
{
MyEventFromDelegate("Value Greater than 5");
i = 0;
}
else
{
i = value;
}
}
}
}
public partial class Form1 : Form
{
public Form1()
{ InitializeComponent(); }
public void Method_To_Call(String rx)
{ MessageBox.Show("This method will be called if greater than 5");}
private void button1_Click(object sender, EventArgs e)
{
SomeClass a = new SomeClass();
a.MyEventFromDelegate +=new MyDelegate(Method_To_Call);
a.I = 12;
}
}
The only concern I have here is when we want to raise an event with the statement
MyEventFromDelegate("Value Greater than 5");
What point is passing a parameters to the event is at this point if later (at button click event) we are actually going to assign it a function to call every time an event is triggered.
In your very simple example - there is no point, because SomeClass instance "a" is very short-lived, and because you are not using rx parameter passed to Method_To_Call.
Your form method button1_Click is connected to the button's Click event through a delegate. Button does not know what code will execute when it is clicked. All it has to do is to signal that is has been clicked. That signal is implemented using a delegate.
Your could have defined your delegate as having an integer parameter where the checked value is passed. Then although the event method would be invoked only when value is greater than 5, inside the event method you could do things differently depending on the actual value.
//declare the delegate
public delegate void MyDelegate(int aValue);
public class SomeClass
{
public event MyDelegate MyEventFromDelegate;
private int i;
public int I
{
get
{ return i; }
set
{
if (value > 5)
{
MyEventFromDelegate(value);
i = 0;
}
else
{
i = value;
}
}
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public void Method_To_Call(int aValue)
{
MessageBox.Show("This method signals that value is greater than 5. Value=" + aValue.ToString());
}
private void button1_Click(object sender, EventArgs e)
{
SomeClass a = new SomeClass();
a.MyEventFromDelegate +=new MyDelegate(Method_To_Call);
a.I = 12;
}
}
Design Question – Polymorphic Event Handling
I’m currently trying to reduce the number of Event Handles in my current project. We have multiple systems that send data over USB. I currently have a routine to read in the messages and parse the initial header details to determine which system the message came from. The headers are a little different, so the EventArgs I created are not the same. Then I notify all “observers” of the change. So what I have right now is the following:
public enum Sub1Enums : byte
{
ID1 = 0x01,
ID2 = 0x02
}
public enum Sub2Enums : ushort
{
ID1 = 0xFFFE,
ID2 = 0xFFFF
}
public class MyEvent1Args
{
public Sub1Enums MessageID;
public byte[] Data;
public MyEvent1Args(Sub1Enums sub1Enum, byte[] data)
{
MessageID = sub1Enum;
Data = data;
}
}
public class MyEvent2Args
{
public Sub2Enums MessageID;
public byte[] Data;
public MyEvent2Args(Sub2Enums sub2Enum, byte[] data)
{
MessageID = sub2Enum;
Data = data;
}
}
Form1 code
public class Form1
{
public delegate void TestHandlerCurrentlyDoing(MyEvent1Args eventArgs1);
public delegate void TestHandlerCurrentlyDoingAlso(MyEvent2Args eventArgs2);
public event TestHandlerCurrentlyDoing mEventArgs1;
public event TestHandlerCurrentlyDoingAlso mEventArgs2;
public Form1()
{
mEventArgs1 += new TestHandlerCurrentlyDoing(Form1_mEventArgs1);
mEventArgs2 += new TestHandlerCurrentlyDoingAlso(Form1_mEventArgs2);
}
void Form1_mEventArgs2(MyEvent2Args eventArgs2)
{
// Do stuff here
Sub2Enums mid = my_event2_args.MessageID;
byte[] data = my_event2_args.Data;
}
void Form1_mEventArgs1(MyEvent1Args eventArgs1)
{
// Do stuff here
Sub1Enums mid = my_event1_args.MessageID;
byte[] data = my_event1_args.Data;
}
And in the parse algorithm I have something like this based on which message it is:
void ParseStuff()
{
if (mEventArgs1 != null)
{
mEventArgs1(new MyEvent1Args(Sub1Enums.ID1, new byte[] { 0x01 }));
}
if (mEventArgs2 != null)
{
mEventArgs2(new MyEvent2Args(Sub2Enums.ID2, new byte[] { 0x02 }));
}
}
What I really want to do is this:
public class Form1
{
public delegate void TestHandlerDesired(MyEvent1Args eventArgs1);
public delegate void TestHandlerDesired(MyEvent2Args eventArgs2);
public event TestHandlerDesired mEventArgs;
public Form1()
{
mEventArgs += new TestHandlerDesired (Form1_mEventArgs1);
mEventArgs += new TestHandlerDesired (Form1_mEventArgs2);
}
}
And for ambiguity reasons we can’t do this. So my question is what would be a better approach to this problem?
If you're trying to reduce the number of event handles in order abstract / simplify the coding you have to do, then applying the Double Dispatch design pattern to your event args would be perfect. It's basically an elegant (but wordy) fix for having to perform safe type casts (/ is instanceof checks)
I could make MyEvent1Args and MyEvent2Args derive from a common base class and do the following:
public class BaseEventArgs : EventArgs
{
public byte[] Data;
}
public class MyEvent1Args : BaseEventArgs
{ … }
public class MyEvent2Args : BaseEventArgs
{ … }
public delegate void TestHandlerWithInheritance(BaseEventArgs baseEventArgs);
public event TestHandlerWithInheritance mTestHandler;
mTestHandler += new TestHandlerWithInheritance(TestHandlerForEvent1Args);
mTestHandler += new TestHandlerWithInheritance(TestHandlerForEvent2Args);
void TestHandlerForEvent1Args(BaseEventArgs baseEventArgs)
{
MyEvent1Args my_event1_args = (baseEventArgs as MyEvent1Args);
if (my_event1_args != null)
{
// Do stuff here
Sub1Enums mid = my_event1_args.MessageID;
byte[] data = my_event1_args.Data;
}
}
void TestHandlerForEvent2Args(BaseEventArgs baseEventArgs)
{
MyEvent2Args my_event2_args = (baseEventArgs as MyEvent2Args);
if (my_event2_args != null)
{
// Do stuff here
Sub2Enums mid = my_event2_args.MessageID;
byte[] data = my_event2_args.Data;
}
}
And in the parse algorithm I have something like this based on which message it is:
if (mTestHandler!= null)
{
mTestHandler (new MyEvent1Args(Sub1Enums.ID1, new byte[] { 0x01 }));
}
if (mTestHandler!= null)
{
mTestHandler (new MyEvent2Args(Sub2Enums.ID2, new byte[] { 0x02 }));
}
Take a break from polymorphism and look into using indirection, specifically the Event Aggregator pattern if you haven't already; Fowler first # http://martinfowler.com/eaaDev/EventAggregator.html and then postings by Jeremy Miller if you need more ideas.
Cheers,
Berryl
You could consider a few options (I am not sure what exactly you want to achieve here):
1. Create a hierarchy of EventArgs and make the observers responsible for filtering stuff they are interested in (this is what you proposed in your answer). This especially makes sense if some observers are interested in multiple types of messages, ideally described by the base class type.
2. Don't use .Net delegates, just implement it yourself such that when you register the delegate it also takes the type of event it expects. This assumes you have done the work from (1), but you want to pass the filtering to your class and not observers
E.g. (untested):
enum MessageType
{
Type1,Type2
}
private Dictionary<MessageType, TestHandlerWithInheritance> handlers;
public void RegisterObserver(MessageType type, TestHandlerWithInheritance handler)
{
if(!handlers.ContainsKey(type))
{
handlers[key] = handler;
}
else
{
handlers[key] = Delegate.Combine(handlers[key] , handler);
}
}
And when a new message arrives, you run the correct delegate from the handlers dictionary.
3. Implement events in the way its done in WinForms, so that you don't have an underlying event for ever exposed event. This makes sense if you expect to have more events than observers.
E.g.:
public event EventHandler SthEvent
{
add
{
base.Events.AddHandler(EVENT_STH, value);
}
remove
{
base.Events.RemoveHandler(EVENT_STH, value);
}
}
public void AddHandler(object key, Delegate value)
{
ListEntry entry = this.Find(key);
if (entry != null)
{
entry.handler = Delegate.Combine(entry.handler, value);
}
else
{
this.head = new ListEntry(key, value, this.head);
}
}
public void RemoveHandler(object key, Delegate value)
{
ListEntry entry = this.Find(key);
if (entry != null)
{
entry.handler = Delegate.Remove(entry.handler, value);
}
}
private ListEntry Find(object key)
{
ListEntry head = this.head;
while (head != null)
{
if (head.key == key)
{
return head;
}
head = head.next;
}
return head;
}
private sealed class ListEntry
{
// Fields
internal Delegate handler;
internal object key;
internal EventHandlerList.ListEntry next;
// Methods
public ListEntry(object key, Delegate handler, EventHandlerList.ListEntry next)
{
this.next = next;
this.key = key;
this.handler = handler;
}
}
Please let me know if you want me to expand on any of the answers.
If you're trying to reduce the number of event handles to save RAM, do what microsoft do (in System.ComponentModel.Component) and use an EventHandlerList to track all of your events. Here is an article that describes conserving memory use with an EventHandlerList, and here is a similar article that's written in C#..
The gist of it is that you can declare a single EventHandlerList (remember to dispose it) in your class, along with a unique key:
public class Foo
{
protected EventHandlerList listEventDelegates = new EventHandlerList();
static readonly object mouseDownEventKey = new object();
...override the event property:
public event MouseEventHandler MouseDown {
add { listEventDelegates.AddHandler(mouseDownEventKey, value); }
remove { listEventDelegates.RemoveHandler(mouseDownEventKey, value); }
}
...and provide a RaiseEvent method:
protected void RaiseMouseDownEvent(MouseEventArgs e)
{
MouseEventHandler handler = (MouseEventHandler) base.Events[mouseDownEventKey];
if (handler != null)
{
handler(this, e);
}
}
Of course, you just reuse the same EventHandlerList for all your events (but with different keys).