INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Jobs

Jobs from Indeed

Cancel and re-enable a CheckListBox ItemCheck event

Cancel and re-enable a CheckListBox ItemCheck event

(OP)
I am trying to find out how to generically cancel and re-enable an event on a CheckListBox.

I could do it this way, if I know the event:

public void cancelevent()
{
checkedListBox1.ItemCheck -= new ItemCheckEventHandler(this.checkedListBox1_ItemCheck);
}

but I have 5 CheckListBoxes that I want to do this for and want to pass the CheckListBox in an disable the ItemCheck event (whatever it is), do something and then re-enable it. In this case, to programmatically check or uncheck a checkbox without the event firing.

Is there something like:

checkListBox1.ItemEvent.<on or off>,

or someway I can get the event name and use that with the above method?

Thanks,

Tom

RE: Cancel and re-enable a CheckListBox ItemCheck event

Hmm, well, the Type class does include a method called GetEvents(). So using some reflection we should be able to get the list of FieldInfo objects and EventInfo objects. Once you have the EventInfo you can use that to register/deregister events from an object. Something like this MIGHT work. As a HUGE warning, this will cause some some issues. I would never use this just to clear events (without removing the dictionary portion) because it is going to basically keep a reference to whichever object provided the Delegate, meaning it won't ever get garbage collected. I would recommend against using the remove all events (in this form) without always calling the rehook so that things can proceed normally after that. May want to consider trying to work some weak references into this. I will test it later.

EDIT: Re-posted with color because god that was hard to read.

CODE --> C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
 
namespace RemoveAllEventsTest
{
    class EventHelper
    {
        static Dictionary<object, List<RemovedEvent>> removedEvents = new Dictionary<object, List<RemovedEvent>>();
 
        private static List<FieldInfo> GetEventFields(Type t)
        {
            List<FieldInfo> fields = new List<FieldInfo>();
 
            EventInfo[] eventInfos = t.GetEvents(BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
            foreach (EventInfo eventInfo in eventInfos)
            {
                Type declaringType = eventInfo.DeclaringType;
                FieldInfo fieldInfo = declaringType.GetField(eventInfo.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
                if (fieldInfo != null)
                    fields.Add(fieldInfo);
            }
 
            return fields;
        }
 
        public static void RehookAllEvent(object obj)
        {
            if (!removedEvents.ContainsKey(obj))
                throw new Exception("Object has not had its events previously removed");
            List<RemovedEvent> events = removedEvents[obj];
            foreach (RemovedEvent ev in events)
                ev.EventInfo.AddEventHandler(obj, ev.Method);
            removedEvents.Remove(obj);
        }
 
        public static void RemoveAllEvents(object obj)
        {
            Type t = obj.GetType();
            List<FieldInfo> eventFields = GetEventFields(t);
            foreach (FieldInfo eventField in eventFields)
            {
                EventInfo eventInfo = t.GetEvent(eventField.Name, BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic);
                if (eventInfo == null)
                    continue;
 
                Delegate eventDelegate = null;
 
                if (!eventField.IsStatic)
                    eventDelegate = eventField.GetValue(obj) as Delegate;
                else
                {
                    MethodInfo methodInfo = t.GetMethod("get_Events", BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Static | BindingFlags.NonPublic);
                    EventHandlerList eventList = methodInfo.Invoke(obj, new object[] { }) as EventHandlerList;
                    if (eventList == null)
                        continue;
 
                    object staticField = eventField.GetValue(obj);
                    eventDelegate = eventList[staticField];
                }
 
                if (eventDelegate == null)
                    continue;
 
                List<RemovedEvent> eventMethods = new List<RemovedEvent>();
                foreach (Delegate method in eventDelegate.GetInvocationList())
                {
                    RemovedEvent re = new RemovedEvent() { EventInfo = eventInfo, Method = method };
                    eventMethods.Add(re);
                    eventInfo.RemoveEventHandler(obj, method);
                }
                removedEvents.Add(obj, eventMethods);
            }
        }
        class RemovedEvent
        {
            public EventInfo EventInfo { get; set; }
            public Delegate Method { get; set; }
        }
    }
} 

RE: Cancel and re-enable a CheckListBox ItemCheck event

I usually set a global boolean flag to true at the start of the code where I'm changing the values of the checkboxes and then set it back to false when I'm done. Then, in the event handler, I add a check for the value of the flag and only process the code in the event handler if the flag is false.

The code I use to force the checked state into all of the child nodes of a tree node that has changed looks something like this:

private void tvRptFolders_AfterCheck(object sender, TreeViewEventArgs e)
{
if (!nodeChecking)
{
nodeChecking = true;
((TreeFolderNode)e.Node).Check(e.Node.Checked);
if (!e.Node.Checked && cbSelAll.Checked)
{
selectAll = true;
cbSelAll.Checked = false;
selectAll = false;
}
nodeChecking = false;
}
}

Something like this could be adapted for use in your CheckListBox.

-Dell

DecisionFirst Technologies - Seven-time SAP BusinessObjects Solution Partner of the Year
www.decisionfirst.com

RE: Cancel and re-enable a CheckListBox ItemCheck event

Ah. If all you're worried about is the single checked event, then yes, it would be much simpler to just disable the event via a bool when you're pro-grammatically updating.

Also, if anyone is looking at this.. after some testing, it seems reflection doesn't make getting at the event's field easy. This will still miss events, but most events follow a pattern where this code will work:

CODE --> C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Reflection;
 
namespace RemoveAllEventsTest
{
    class EventHelper
    {
        static Dictionary<object, List<RemovedEvent>> removedEvents = new Dictionary<object, List<RemovedEvent>>();
        static BindingFlags AllFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic;
        private static List<EventFound> GetEventFields(Type t)
        {
            List<EventFound> fields = new List<EventFound>();
 
            EventInfo[] eventInfos = t.GetEvents();
            foreach (EventInfo eventInfo in eventInfos)
            {
                Type declaringType = eventInfo.DeclaringType;
                FieldInfo fieldInfo = declaringType.GetField(eventInfo.Name, AllFlags);
                if (fieldInfo == null)
                    fieldInfo = declaringType.GetField("Event" + eventInfo.Name, AllFlags);
                if (fieldInfo != null)
                    fields.Add(new EventFound() { FieldInfo = fieldInfo, EventInfo = eventInfo });
            }
 
            return fields;
        }
 
        public static void ToggleAllEvents(object obj)
        {
            if (removedEvents.ContainsKey(obj))
                RehookAllEvent(obj);
            else
                RemoveAllEvents(obj);
        }
 
        public static void RehookAllEvent(object obj)
        {
            if (!removedEvents.ContainsKey(obj))
                throw new Exception("Object has not had its events previously removed");
            List<RemovedEvent> events = removedEvents[obj];
            foreach (RemovedEvent ev in events)
                ev.EventInfo.AddEventHandler(obj, ev.Method);
            removedEvents.Remove(obj);
        }
 
        public static void RemoveAllEvents(object obj)
        {
            Type t = obj.GetType();
            List<EventFound> eventFields = GetEventFields(t);
            foreach (EventFound eventField in eventFields)
            {
                Delegate eventDelegate = null;
 
                if (!eventField.FieldInfo.IsStatic)
                    eventDelegate = eventField.FieldInfo.GetValue(obj) as Delegate;
                else
                {
                    MethodInfo methodInfo = t.GetMethod("get_Events", AllFlags);
                    EventHandlerList eventList = methodInfo.Invoke(obj, new object[] { }) as EventHandlerList;
                    if (eventList == null)
                        continue;
 
                    object staticField = eventField.FieldInfo.GetValue(obj);
                    eventDelegate = eventList[staticField];
                }
 
                if (eventDelegate == null)
                    continue;
 
                List<RemovedEvent> eventMethods = new List<RemovedEvent>();
                foreach (Delegate method in eventDelegate.GetInvocationList())
                {
                    RemovedEvent re = new RemovedEvent() { EventInfo = eventField.EventInfo, Method = method };
                    eventMethods.Add(re);
                    eventField.EventInfo.RemoveEventHandler(obj, method);
                }
                removedEvents.Add(obj, eventMethods);
            }
        }
        class RemovedEvent
        {
            public EventInfo EventInfo { get; set; }
            public Delegate Method { get; set; }
        }
        class EventFound
        {
            public EventInfo EventInfo { get; set; }
            public FieldInfo FieldInfo { get; set; }
        }
    }
} 

Working test code:

CODE --> C#

using System;
using System.Windows.Forms;
 
namespace RemoveAllEventsTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }
 
        private void button1_Click(object sender, EventArgs e)
        {
            MessageBox.Show("Hello!");
        }
 
        private void button2_Click(object sender, EventArgs e)
        {
            EventHelper.ToggleAllEvents(button1);
        }
    }
} 

RE: Cancel and re-enable a CheckListBox ItemCheck event

Changed it to include Weak References. Tested by disposing an object I had done an remove events with. Seems to work fine.

CODE --> C#

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
 
namespace CustomLibraries
{
    class EventHelper
    {
        static List<RemovedEvents> removedEvents = new List<RemovedEvents>();
        static BindingFlags AllFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance | BindingFlags.Static | BindingFlags.NonPublic;
        private static List<EventFound> GetEventFields(Type t)
        {
            List<EventFound> fields = new List<EventFound>();
 
            EventInfo[] eventInfos = t.GetEvents();
            foreach (EventInfo eventInfo in eventInfos)
            {
                Type declaringType = eventInfo.DeclaringType;
                FieldInfo fieldInfo = declaringType.GetField(eventInfo.Name, AllFlags);
                if (fieldInfo == null)
                    fieldInfo = declaringType.GetField("Event" + eventInfo.Name, AllFlags);
                if (fieldInfo != null)
                    fields.Add(new EventFound() { FieldInfo = fieldInfo, EventInfo = eventInfo });
            }
 
            return fields;
        }
 
        public static void ToggleAllEvents(object obj)
        {
            if (removedEvents.Where(r => r.Object == obj).Count() > 0)
                RehookAllEvent(obj);
            else
                RemoveAllEvents(obj, true);
        }
 
        public static bool RehookAllEvent(object obj)
        {
            var item = removedEvents.Where(r => r.Object == obj);
            if (item.Count() == 0)
                return false;
            foreach (RemovedEvent ev in item.First().Events)
                if (ev.Method != null && ev.EventInfo != null)
                    ev.EventInfo.AddEventHandler(obj, ev.Method);
            removedEvents.Remove(item.First());
            return true;
        }
 
        public static void RemoveAllEvents(object obj, bool storeEvents)
        {
            Type t = obj.GetType();
            List<EventFound> eventFields = GetEventFields(t);
            foreach (EventFound eventField in eventFields)
            {
                Delegate eventDelegate = null;
 
                if (!eventField.FieldInfo.IsStatic)
                    eventDelegate = eventField.FieldInfo.GetValue(obj) as Delegate;
                else
                {
                    MethodInfo methodInfo = t.GetMethod("get_Events", AllFlags);
                    EventHandlerList eventList = methodInfo.Invoke(obj, new object[] { }) as EventHandlerList;
                    if (eventList == null)
                        continue;
 
                    object staticField = eventField.FieldInfo.GetValue(obj);
                    eventDelegate = eventList[staticField];
                }
 
                if (eventDelegate == null)
                    continue;
 
                RemovedEvents res = null;
                if (storeEvents)
                    res = new RemovedEvents(obj);
                foreach (Delegate method in eventDelegate.GetInvocationList())
                {
                    if (storeEvents)
                    {
                        RemovedEvent re = new RemovedEvent(eventField.EventInfo, method, obj);
                        res.AddEvent(re);
                    }
                    eventField.EventInfo.RemoveEventHandler(obj, method);
                }
                if (storeEvents)
                    removedEvents.Add(res);
            }
        }
        class RemovedEvents
        {
            private List<RemovedEvent> _RemovedEvents;
            private WeakReference _Object;
 
            public object Object { get { return _Object.Target; } }
            public List<RemovedEvent> Events { get { return _RemovedEvents; } }
 
            public RemovedEvents(object obj)
            {
                _Object = new WeakReference(obj, false);
                _RemovedEvents = new List<RemovedEvent>();
            }
            public void AddEvent(RemovedEvent re)
            {
                _RemovedEvents.Add(re);
            }
        }
        class RemovedEvent
        {
            public EventInfo EventInfo { get { return _EventInfo.Target as EventInfo; } }
            public Delegate Method { get { return _Method.Target as Delegate; } }
            public object Object { get { return _Object.Target; } }
 
            private WeakReference _EventInfo;
            private WeakReference _Method;
            private WeakReference _Object;
 
            public RemovedEvent(EventInfo ev, Delegate m, object target)
            {
                _EventInfo = new WeakReference(ev, false);
                _Method = new WeakReference(m, false);
                _Object = new WeakReference(target, false);
            }
        }
        class EventFound
        {
            public EventInfo EventInfo { get; set; }
            public FieldInfo FieldInfo { get; set; }
        }
    }
} 

RE: Cancel and re-enable a CheckListBox ItemCheck event

New to C#, simple question.

I was told many times: "Nothing equals to NULL, not even a NULL".

But what I see here:

CODE

if (fieldInfo == null) 

ponder

Have fun.

---- Andy

There is a great need for a sarcasm font.

RE: Cancel and re-enable a CheckListBox ItemCheck event

If you're working in SQL a database, you need to use "is null" or "is not null" - in those terms, nothing equals to null". However, in many programming languages, including C# and Java, you use "== null" to determine whether an object has a null value.

-Dell

DecisionFirst Technologies - Seven-time SAP BusinessObjects Solution Partner of the Year
www.decisionfirst.com

RE: Cancel and re-enable a CheckListBox ItemCheck event

In C# all objects are just references - they don't store the value, they store a reference to where the object is in memory. This is done in the background of course and you don't have to map it out yourself, but you have to have some way to check whether your variable actually has a valid reference or not. If the variable doesn't currently point to an instantiated object, it said to be null. null is a literal in the C# language that means "a reference to nothing", basically.

Edit: See the MSDN for more information if you want it https://msdn.microsoft.com/en-us/library/edakx9da....

C# Value Types: https://msdn.microsoft.com/en-us/library/s1ax56ch....

C# Reference Types: https://msdn.microsoft.com/en-us/library/490f96s2....

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members!

Resources

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close