I've read this answer.
It just tell me how to remove the click event from a button control. I want to know how to change the code (especially the GetField("EventClick"...
part!) so I can do the same thing with other controls. For example, I want to remove the TextChanged
event of a TextBox
.
And I also want to know how to re-attach the event handler.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
if (textBox1.Text.Length < 10) return;
MessageBox.Show("do something");
}
private void Form1_Load(object sender, EventArgs e)
{
Tools.mkTextBoxWithPlaceholder(textBox1, "hi, input here...");
}
}
class Tools
{
public static void mkTextBoxWithPlaceholder(TextBox tb, string placeholder)
{
tb.Tag = placeholder;
tb.GotFocus += new EventHandler(tb_GotFocus);
tb.LostFocus += new EventHandler(tb_LostFocus);
}
private static void tb_GotFocus(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
tb.Clear();
}
private static void tb_LostFocus(object sender, EventArgs e)
{
TextBox tb = sender as TextBox;
//TODO Remove the TextChanged event handler here.
tb.Text = tb.Tag as string;
//TODO Reattach the TextChanged event handler here.
}
}
With the code above, the textBox1 will have a function like placeholder.Maybe you can just give me some help on how to add the placeholder to a textbox. That's what I want.
Remove
Mybutton.event -= methodname;
Reattach
Mybutton.event += methodname;
Here is a solution to your problem, according to this post of mine.
These helper methods let you manipulate any event for a specific control:
// Also searches up the inheritance hierarchy
private static FieldInfo GetStaticNonPublicFieldInfo(Type type, string name)
{
FieldInfo fi;
do
{
fi = type.GetField(name, BindingFlags.Static | BindingFlags.NonPublic);
type = type.BaseType;
} while (fi == null && type != null);
return fi;
}
private static object GetControlEventKey(Control c, string eventName)
{
Type type = c.GetType();
FieldInfo eventKeyField = GetStaticNonPublicFieldInfo(type, "Event" + eventName);
if (eventKeyField == null)
{
if (eventName.EndsWith("Changed"))
eventKeyField = GetStaticNonPublicFieldInfo(type, "Event" + eventName.Remove(eventName.Length - 7)); // remove "Changed"
else
eventKeyField = GetStaticNonPublicFieldInfo(type, "EVENT_" + eventName.ToUpper());
if (eventKeyField == null)
{
// Not all events in the WinForms controls use this pattern.
// Other methods can be used to search for the event handlers if required.
return null;
}
}
return eventKeyField.GetValue(c);
}
private static EventHandlerList GetControlEventHandlerList(Control c)
{
Type type = c.GetType();
PropertyInfo pi = type.GetProperty("Events",
BindingFlags.NonPublic | BindingFlags.Instance);
return (EventHandlerList)pi.GetValue(c, null);
}
and then you can use them to temporarily detach an event handler:
private static void tb_LostFocus(object sender, EventArgs e)
{
TextBox tb = (TextBox)sender;
var eventList = GetControlEventHandlerList(tb);
var eventKey = GetControlEventKey(tb, "TextChanged");
// Remove the handlers
var handlers = eventList[eventKey];
eventList.RemoveHandler(eventKey, handlers);
// ... perform your task
// Reattach the handlers
eventList.AddHandler(eventKey, handlers);
}
If you want to know what is really happening here, read on.
Windows Forms uses the EventHandlerList
class to maintain control events. Every event is accessed using a simple key of type object. Keys are stored in private fields of the control. The only way to access this data is using reflection, but we should know the name of the event key field. By decompiling the the Control
class and it's descendants, we can see that the keys use different names. I extracted three common naming pattern among the keys, and used them in the GetControlEventKey
method.
This is the mechanism that WinForms controls use to hold the event handlers. There is no special thing about it. It is just a design choice.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With