我正在使用c#,我有一个实例化很多PictureBox按钮的项目。我还编写了所有click,hover,mouseUp,mouseDown事件方法。如何从字符串名称调用方法,以便我不必手动编写所有这些方法?提前谢谢,卡森
Dictionary<string, PictureBox> buttonList = new Dictionary<string,PictureBox>();
string buttonName = "button_file";
buttonList[buttonName].Click += new EventHandler(buttonName + "_click");
public void button_file_click(object sender, EventArgs e)
{
// do on click stuff here
}
答案 0 :(得分:2)
如果设置按钮的Name属性,则可以这样:
buttonList[buttonName].Name = buttonName;
buttonList[buttonName].Click += ButtonClick;
并且只有一个元数据所有按钮点击,但按照他们的名字:
public void ButtonClick(object sender, EventArgs e)
{
var btn = (Button)sender;
btn.Text = btn.Name; //only for demo
}
但你可以完全编写自己的方法:
buttonList[buttonName].Click += (s,e)=> clickEvent(buttonList[buttonName], buttonName);
这是一个简短的lambda函数,它接受Click事件单一的相应参数并激活你的自定义函数clickEvent
:
public void clickEvent(Button thePressedButton, string nameOfPresedButton)
{
thePressedButton.Text = btn.nameOfPresedButton; //only for demo
}
答案 1 :(得分:0)
从您的示例代码中,我假设您希望所有人都拨打<style>
.s4-wpcell-plain{
text-align: -webkit-center;
}
</style>
<table style="width:100%" cellpadding="0" cellspacing="0">
<tbody>
<tr>
<td id="MSOZoneCell_WebPartWPQ2" valign="top" class="s4-wpcell-plain">
<!-- content -->
</td>
</tr>
</tbody>
</table>
。
在这种情况下,只需将eventhandler设置为该方法:
button_file_click
答案 2 :(得分:0)
方法名称还不够......你还需要一个类名...但假设该方法属于当前类(this
),你可以使用Reflection来做到这一点: / p>
public void ExecuteMethod(string methodName)
{
var methodInfo = this.GetType().GetMethod(methodName);
methodInfo.Invoke(this, new [] {});
}
但您不能将上述内容分配给某个事件,因为它不是正确的代理类型;大多数事件处理程序需要sender
和EventArgs
。因此,为了使您的代码更有效,您需要更多的粘合剂:
Dictionary<string, PictureBox> buttonList = new Dictionary<string,PictureBox>();
string buttonName = "button_file";
buttonList[buttonName].Click += GetHandler(buttonName + "_click");
public Action<object, EventArgs> GetHandler(string handlerName)
{
var methodInfo = this.GetType().GetMethod(handlerName, new Type[] {typeof(object), typeof(EventArgs)});
return new Action<object, EventArgs> (sender, eventArgs) => methodInfo.Invoke(this, new [] {sender, eventArgs});
}
这里的想法是GetHandler
返回带有正确签名的Action
(按顺序接受一个对象和一个EventArgs),写成Action<object, EventArgs>
。 GetHandler
方法使用反射在当前类中查找正确的方法,然后创建一个lambda表达式,通过反射调用该方法,将参数作为数组传递。
上面当然只是一个例子......将代理存储在第一次加载页面时计算的静态字典中可能会更好。
话虽如此,如果您正在寻找基于运行时参数的事件处理灵活性,更好的方法可能是使用Command event,这允许您将字符串传递给处理程序,然后可以根据字符串的内容采取不同的操作。这样你就可以对处理程序引用进行硬编码,但仍然会软编码它将做什么。
Dictionary<string, PictureBox> buttonList = new Dictionary<string,PictureBox>();
string buttonName = "button_file";
buttonList[buttonName].Command += buttonList_Command;
buttonList[buttonName].CommandName = buttonName;
protected void buttonList_Command(object sender, CommandEventArgs e)
{
switch (e.CommandName)
{
case buttonName:
//Do stuff for button_file
break;
case "Foo":
//Do stuff for some other button named foo
break;
default:
throw new InvalidOperationException();
}
}
答案 3 :(得分:0)
您可以使用反射按名称查找类的方法,然后使用该方法创建事件处理程序委托。例如:
void bindHandler(string buttonName)
{
string methodName = buttonName + "_click";
System.Reflection.MethodInfo m = this.GetType().GetMethods().FirstOrDefault(x => x.Name == buttonName + "_click");
PictureBox button = buttonList[buttonName];
Delegate handler = Delegate.CreateDelegate(typeof(EventHandler), this, m);
button.Click += (EventHandler)handler;
}
填写工作代码:
namespace WindowsFormsApp1Cs
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
MyClass c = new MyClass();
foreach (var item in c.buttonList)
{
this.Controls.Add(item.Value);
}
}
}
public class MyClass
{
public Dictionary<string, PictureBox> buttonList;
public delegate void MyClickHandler(object sender, EventArgs e);
public MyClass()
{
buttonList = new Dictionary<string, PictureBox>();
buttonList.Add("button_file_1", new PictureBox() { Width = 100, Height = 100, Name = "button_file_1", Anchor = AnchorStyles.Top | AnchorStyles.Left, Top = (buttonList.Count * 100) + 10, Left = 10, ImageLocation="0.jpg" });
buttonList.Add("button_file_2", new PictureBox() { Width = 100, Height = 100, Name = "button_file_2", Anchor = AnchorStyles.Top | AnchorStyles.Left, Top = (buttonList.Count * 100) + 10, Left = 10, ImageLocation = "0.jpg" });
buttonList.Add("button_file_3", new PictureBox() { Width = 100, Height = 100, Name = "button_file_3", Anchor = AnchorStyles.Top | AnchorStyles.Left, Top = (buttonList.Count * 100) + 10, Left = 10, ImageLocation = "0.jpg" });
foreach (var item in buttonList)
{
bindHandler(item.Key);
}
}
void bindHandler(string buttonName)
{
string methodName = buttonName + "_click";
System.Reflection.MethodInfo m = this.GetType().GetMethods().FirstOrDefault(x => x.Name == buttonName + "_click");
PictureBox button = buttonList[buttonName];
Delegate handler = Delegate.CreateDelegate(typeof(EventHandler), this, m);
button.Click += (EventHandler)handler;
}
public void button_file_1_click(object sender, EventArgs e)
{
Debug.WriteLine("button_file_1_click");
}
public void button_file_2_click(object sender, EventArgs e)
{
Debug.WriteLine("button_file_2_click");
}
public void button_file_3_click(object sender, EventArgs e)
{
Debug.WriteLine("button_file_3_click");
}
}
}