Min*_*eng 5 c# event-handling winforms
我读过这个答案.它只是告诉我如何从按钮控件中删除click事件.我想知道如何更改代码(特别是GetField("EventClick"...
部分!)所以我可以用其他控件做同样的事情.例如,我想删除a的TextChanged
事件TextBox
.我还想知道如何重新附加事件处理程序.
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.
}
}
Run Code Online (Sandbox Code Playgroud)
使用上面的代码,textBox1将具有像占位符这样的函数.也许你可以给我一些关于如何将占位符添加到文本框的帮助.这就是我想要的.
小智 5
去掉
Mybutton.event -= methodname;
Run Code Online (Sandbox Code Playgroud)
重新连接
Mybutton.event += methodname;
Run Code Online (Sandbox Code Playgroud)
根据我的这篇文章,这是您问题的解决方案。
这些帮助器方法允许您操纵特定控件的任何事件:
// 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);
}
Run Code Online (Sandbox Code Playgroud)
然后您可以使用它们暂时分离事件处理程序:
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);
}
Run Code Online (Sandbox Code Playgroud)
如果您想知道这里到底发生了什么,请继续阅读。
Windows 窗体使用该类EventHandlerList
来维护控件事件。每个事件都可以使用对象类型的简单键来访问。密钥存储在控件的私有字段中。访问此数据的唯一方法是使用反射,但我们应该知道事件键字段的名称。通过反编译该类Control
及其后代,我们可以看到键使用不同的名称。我提取了键中的三种常见命名模式,并在GetControlEventKey
方法中使用了它们。
这是 WinForms 控件用来保存事件处理程序的机制。这没有什么特别的。这只是一个设计选择。
归档时间: |
|
查看次数: |
5280 次 |
最近记录: |