Home All Groups Group Topic Archive Search About

How to Verify if EventHandler for ValueChanged has been set?

Author
16 Dec 2008 6:04 PM
richard.martino
I have a huge Windows desktop application with over 100 individual
controls, like TextBox, NumericUpDown, ComboBox, etc.

I want each one to have its ValueChanged (or TextChanged) event
handler set, like:

-----------

System.Windows.Forms.TextBox cityTextBox;

cityTextBox = new TextBox();
cityTextBox.TextChanged += new EventHandler(cityTextBox_TextChanged);

-----------

I can loop through all of the controls of the application starting
with this.Controls and, recursively their children, finding everyone
of my 100 individual controls.

I want my software to verify if I have every TextChanged or
ValueChanged event handler set.

Any clues?

Thanks

Author
16 Dec 2008 6:12 PM
Nicholas Paldino [.NET/C# MVP]
Richard,

    You would have to use reflection for this, as you don't have access to
the event handler list from outside the instance that exposes the event.

    You would have to look for the backing field for the delegate, but the
thing is, there is no guaranteed linking between that field and the event
exposed.  For the standard event implementation (no add/remove handlers), it
should work, but you might run into some custom add/remove handlers and it
won't be that easy to figure out what the backing field for the event is.

    Are you doing this for unit testing, or within your app?  If you are
doing it within your app, I would recommend making this a unit test or maybe
a custom rule for FxCop.

--
          - Nicholas Paldino [.NET/C# MVP]
          - mvp@spam.guard.caspershouse.com

<richard.mart***@raymondjames.com> wrote in message
Show quoteHide quote
news:6b0427f8-3b02-406a-af2f-b8145011866f@v18g2000vbb.googlegroups.com...
>I have a huge Windows desktop application with over 100 individual
> controls, like TextBox, NumericUpDown, ComboBox, etc.
>
> I want each one to have its ValueChanged (or TextChanged) event
> handler set, like:
>
> -----------
>
> System.Windows.Forms.TextBox cityTextBox;
>
> cityTextBox = new TextBox();
> cityTextBox.TextChanged += new EventHandler(cityTextBox_TextChanged);
>
> -----------
>
> I can loop through all of the controls of the application starting
> with this.Controls and, recursively their children, finding everyone
> of my 100 individual controls.
>
> I want my software to verify if I have every TextChanged or
> ValueChanged event handler set.
>
> Any clues?
>
> Thanks
>
>
Are all your drivers up to date? click for free checkup

Author
16 Dec 2008 6:33 PM
richard.martino
On Dec 16, 1:12 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.com> wrote:
Show quoteHide quote
> Richard,
>
>     You would have to use reflection for this, as you don't have access to
> the event handler list from outside the instance that exposes the event.
>
>     You would have to look for the backing field for the delegate, but the
> thing is, there is no guaranteed linking between that field and the event
> exposed.  For the standard event implementation (no add/remove handlers), it
> should work, but you might run into some custom add/remove handlers and it
> won't be that easy to figure out what the backing field for the event is.
>
>     Are you doing this for unit testing, or within your app?  If you are
> doing it within your app, I would recommend making this a unit test or maybe
> a custom rule for FxCop.
>
> --
>           - Nicholas Paldino [.NET/C# MVP]
>           - m...@spam.guard.caspershouse.com
>
> <richard.mart***@raymondjames.com> wrote in message
>
> news:6b0427f8-3b02-406a-af2f-b8145011866f@v18g2000vbb.googlegroups.com...
>
>
>
> >I have a huge Windows desktop application with over 100 individual
> > controls, like TextBox, NumericUpDown, ComboBox, etc.
>
> > I want each one to have its ValueChanged (or TextChanged) event
> > handler set, like:
>
> > -----------
>
> > System.Windows.Forms.TextBox cityTextBox;
>
> > cityTextBox = new TextBox();
> > cityTextBox.TextChanged += new EventHandler(cityTextBox_TextChanged);
>
> > -----------
>
> > I can loop through all of the controls of the application starting
> > with this.Controls and, recursively their children, finding everyone
> > of my 100 individual controls.
>
> > I want my software to verify if I have every TextChanged or
> > ValueChanged event handler set.
>
> > Any clues?
>
> > Thanks- Hide quoted text -
>
> - Show quoted text -

Nicholas:

Yes, I have tried reflection as follows:

----------

using System.Reflection;

System.Type type = cityTextBox.GetType();

EventInfo eventInfo = type.GetEvent("TextChanged",
BindingFlags.Instance | BindingFlags.Public);

MethodInfo methodInfo = eventInfo.GetRaiseMethod(true);

//
// However, methodInfo always comes back null.
//
----------

Is the above code what you had in mind?
Author
16 Dec 2008 6:38 PM
Nicholas Paldino [.NET/C# MVP]
Richard,

    From the remarks of the documentation for GetRaiseMethod:

This method returns a null reference (Nothing in Visual Basic) for events
declared with the C# event keyword or the Visual Basic Event keyword. This
is because the C# and Visual Basic compilers do not generate such a method.

    Because there is no guarantee about how the delegate chain is stored for
the event (basically, it's like a property, you don't know what is being
used to store what is returned to you when you call the property), there is
really no way to get that list for inspection with certainty.

--
          - Nicholas Paldino [.NET/C# MVP]
          - mvp@spam.guard.caspershouse.com

<richard.mart***@raymondjames.com> wrote in message
news:6b9b3795-ad42-4460-b598-17582f09dbd2@k1g2000prb.googlegroups.com...
On Dec 16, 1:12 pm, "Nicholas Paldino [.NET/C# MVP]"
<m...@spam.guard.caspershouse.com> wrote:
Show quoteHide quote
> Richard,
>
> You would have to use reflection for this, as you don't have access to
> the event handler list from outside the instance that exposes the event.
>
> You would have to look for the backing field for the delegate, but the
> thing is, there is no guaranteed linking between that field and the event
> exposed. For the standard event implementation (no add/remove handlers),
> it
> should work, but you might run into some custom add/remove handlers and it
> won't be that easy to figure out what the backing field for the event is.
>
> Are you doing this for unit testing, or within your app? If you are
> doing it within your app, I would recommend making this a unit test or
> maybe
> a custom rule for FxCop.
>
> --
> - Nicholas Paldino [.NET/C# MVP]
> - m...@spam.guard.caspershouse.com
>
> <richard.mart***@raymondjames.com> wrote in message
>
> news:6b0427f8-3b02-406a-af2f-b8145011866f@v18g2000vbb.googlegroups.com...
>
>
>
> >I have a huge Windows desktop application with over 100 individual
> > controls, like TextBox, NumericUpDown, ComboBox, etc.
>
> > I want each one to have its ValueChanged (or TextChanged) event
> > handler set, like:
>
> > -----------
>
> > System.Windows.Forms.TextBox cityTextBox;
>
> > cityTextBox = new TextBox();
> > cityTextBox.TextChanged += new EventHandler(cityTextBox_TextChanged);
>
> > -----------
>
> > I can loop through all of the controls of the application starting
> > with this.Controls and, recursively their children, finding everyone
> > of my 100 individual controls.
>
> > I want my software to verify if I have every TextChanged or
> > ValueChanged event handler set.
>
> > Any clues?
>
> > Thanks- Hide quoted text -
>
> - Show quoted text -

Nicholas:

Yes, I have tried reflection as follows:

----------

using System.Reflection;

System.Type type = cityTextBox.GetType();

EventInfo eventInfo = type.GetEvent("TextChanged",
BindingFlags.Instance | BindingFlags.Public);

MethodInfo methodInfo = eventInfo.GetRaiseMethod(true);

//
// However, methodInfo always comes back null.
//
----------

Is the above code what you had in mind?
Author
16 Dec 2008 8:04 PM
yuriylsh
If you still going to use reflection, you can use something like that:

private bool AreListenersAdded(TextBox control, string eventName)
    {
        var controlType = control.GetType();

            var fields = controlType.GetFields(BindingFlags.NonPublic |
BindingFlags.Static | BindingFlags.Instance);
            var eventField = fields.SingleOrDefault(f => f.Name == "Event" +
eventName);
            if (eventField != null)
            {
                var eventsProperty = (typeof(Control)).GetProperty("Events",
BindingFlags.Instance | BindingFlags.NonPublic);
                var events = eventsProperty.GetValue(control, null) as
EventHandlerList;
                if (events != null)
                {
                    var textChangedEvent = eventField.GetValue(control);
                    var eventDelegate = events[textChangedEvent];
                    if (eventDelegate != null)
                        return eventDelegate.GetInvocationList().Length > 0;
                }

            }


        return false;
    }

<richard.mart***@raymondjames.com> wrote in message
Show quoteHide quote
news:6b9b3795-ad42-4460-b598-17582f09dbd2@k1g2000prb.googlegroups.com...
> On Dec 16, 1:12 pm, "Nicholas Paldino [.NET/C# MVP]"
> <m...@spam.guard.caspershouse.com> wrote:
>> Richard,
>>
>>     You would have to use reflection for this, as you don't have access
>> to
>> the event handler list from outside the instance that exposes the event.
>>
>>     You would have to look for the backing field for the delegate, but
>> the
>> thing is, there is no guaranteed linking between that field and the event
>> exposed.  For the standard event implementation (no add/remove handlers),
>> it
>> should work, but you might run into some custom add/remove handlers and
>> it
>> won't be that easy to figure out what the backing field for the event is.
>>
>>     Are you doing this for unit testing, or within your app?  If you are
>> doing it within your app, I would recommend making this a unit test or
>> maybe
>> a custom rule for FxCop.
>>
>> --
>>           - Nicholas Paldino [.NET/C# MVP]
>>           - m...@spam.guard.caspershouse.com
>>
>> <richard.mart***@raymondjames.com> wrote in message
>>
>> news:6b0427f8-3b02-406a-af2f-b8145011866f@v18g2000vbb.googlegroups.com...
>>
>>
>>
>> >I have a huge Windows desktop application with over 100 individual
>> > controls, like TextBox, NumericUpDown, ComboBox, etc.
>>
>> > I want each one to have its ValueChanged (or TextChanged) event
>> > handler set, like:
>>
>> > -----------
>>
>> > System.Windows.Forms.TextBox cityTextBox;
>>
>> > cityTextBox = new TextBox();
>> > cityTextBox.TextChanged += new EventHandler(cityTextBox_TextChanged);
>>
>> > -----------
>>
>> > I can loop through all of the controls of the application starting
>> > with this.Controls and, recursively their children, finding everyone
>> > of my 100 individual controls.
>>
>> > I want my software to verify if I have every TextChanged or
>> > ValueChanged event handler set.
>>
>> > Any clues?
>>
>> > Thanks- Hide quoted text -
>>
>> - Show quoted text -
>
> Nicholas:
>
> Yes, I have tried reflection as follows:
>
> ----------
>
> using System.Reflection;
>
> System.Type type = cityTextBox.GetType();
>
> EventInfo eventInfo = type.GetEvent("TextChanged",
> BindingFlags.Instance | BindingFlags.Public);
>
> MethodInfo methodInfo = eventInfo.GetRaiseMethod(true);
>
> //
> // However, methodInfo always comes back null.
> //
> ----------
>
> Is the above code what you had in mind?
Author
16 Dec 2008 10:28 PM
Berryl Hesh
Richard

Did you solve this?

Rhino has an event raiser that works well with interfaces only. It's hard to
believe that somebody doesn't have some sort of relection based tool you
could use to verify an event is wired or better yet, invoke it in a unit
test. I haven't found it yet though so wondering if you did.

Thanks,
Berryl


Show quoteHide quote
"Nicholas Paldino [.NET/C# MVP]" <mvp@spam.guard.caspershouse.com> wrote in
message news:e3tezn6XJHA.4380@TK2MSFTNGP06.phx.gbl...
> Richard,
>
>    You would have to use reflection for this, as you don't have access to
> the event handler list from outside the instance that exposes the event.
>
>    You would have to look for the backing field for the delegate, but the
> thing is, there is no guaranteed linking between that field and the event
> exposed.  For the standard event implementation (no add/remove handlers),
> it should work, but you might run into some custom add/remove handlers and
> it won't be that easy to figure out what the backing field for the event
> is.
>
>    Are you doing this for unit testing, or within your app?  If you are
> doing it within your app, I would recommend making this a unit test or
> maybe a custom rule for FxCop.
>
> --
>          - Nicholas Paldino [.NET/C# MVP]
>          - mvp@spam.guard.caspershouse.com
>
> <richard.mart***@raymondjames.com> wrote in message
> news:6b0427f8-3b02-406a-af2f-b8145011866f@v18g2000vbb.googlegroups.com...
>>I have a huge Windows desktop application with over 100 individual
>> controls, like TextBox, NumericUpDown, ComboBox, etc.
>>
>> I want each one to have its ValueChanged (or TextChanged) event
>> handler set, like:
>>
>> -----------
>>
>> System.Windows.Forms.TextBox cityTextBox;
>>
>> cityTextBox = new TextBox();
>> cityTextBox.TextChanged += new EventHandler(cityTextBox_TextChanged);
>>
>> -----------
>>
>> I can loop through all of the controls of the application starting
>> with this.Controls and, recursively their children, finding everyone
>> of my 100 individual controls.
>>
>> I want my software to verify if I have every TextChanged or
>> ValueChanged event handler set.
>>
>> Any clues?
>>
>> Thanks
>>
>>
>
>
Author
17 Dec 2008 3:48 PM
richard.martino
Berryl:

No, I have not solved this.

I have this belief (from starting in assembler 30 years ago) that a
software engineer can write any software to do anything.  Somehow the
C# language is lacking an EventInfo.GetValue() method, like
PropertyInfo.GetValue() and FieldInfo.GetValue().

The suggestion that yuriy***@hotmail.com proposed seems to be written
in a language other than C#, and I could not port it over to C#
because some of the methods that he calls are not in C#.

I prefer to have my own software check for this rather than rely on an
external tool.

My overall goal is to verify that every user facing control has a
ValueChanged (or TextChanged) event handler defined.  For the time
being, I will settle for my eyeballs and a good testing department.

Show quoteHide quote
On Dec 16, 5:28 pm, "Berryl Hesh" <efing***@yahoo.com> wrote:
> Richard
>
> Did you solve this?
>
> Rhino has an event raiser that works well with interfaces only. It's hard to
> believe that somebody doesn't have some sort of relection based tool you
> could use to verify an event is wired or better yet, invoke it in a unit
> test. I haven't found it yet though so wondering if you did.
>
> Thanks,
> Berryl
>
> "Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote in
> messagenews:e3tezn6XJHA.4***@TK2MSFTNGP06.phx.gbl...
>
>
Author
18 Dec 2008 4:25 AM
Berryl Hesh
You could always do something like this, I suppose you know:
New Modified class ===========
        public event EventHandler ValueChanged;
        public bool ValueChangedIsWired() { return ValueChanged!= null; }
Test class ===========
        foreach(var newClass in newClassCollection) {
            if(!newClass.ValueChangedIsWired)
            // throw exception, shoot somebody, etc.
        }

I wonder why C# doesn't havesome EventInfo class though. The you could do
what you want without breaking encapsulation.

Good luck with it - BH


<richard.mart***@raymondjames.com> wrote in message
news:4e423cc4-3d9c-452c-b3f7-c687bb0e41c8@w1g2000prk.googlegroups.com...
Berryl:

No, I have not solved this.

I have this belief (from starting in assembler 30 years ago) that a
software engineer can write any software to do anything.  Somehow the
C# language is lacking an EventInfo.GetValue() method, like
PropertyInfo.GetValue() and FieldInfo.GetValue().

The suggestion that yuriy***@hotmail.com proposed seems to be written
in a language other than C#, and I could not port it over to C#
because some of the methods that he calls are not in C#.

I prefer to have my own software check for this rather than rely on an
external tool.

My overall goal is to verify that every user facing control has a
ValueChanged (or TextChanged) event handler defined.  For the time
being, I will settle for my eyeballs and a good testing department.

Show quoteHide quote
On Dec 16, 5:28 pm, "Berryl Hesh" <efing***@yahoo.com> wrote:
> Richard
>
> Did you solve this?
>
> Rhino has an event raiser that works well with interfaces only. It's hard
> to
> believe that somebody doesn't have some sort of relection based tool you
> could use to verify an event is wired or better yet, invoke it in a unit
> test. I haven't found it yet though so wondering if you did.
>
> Thanks,
> Berryl
>
> "Nicholas Paldino [.NET/C# MVP]" <m...@spam.guard.caspershouse.com> wrote
> in
> messagenews:e3tezn6XJHA.4***@TK2MSFTNGP06.phx.gbl...
>
>

Bookmark and Share