如何将变量传递给按钮事件方法?

时间:2011-01-27 11:16:42

标签: c# events

当我单击按钮时,我需要能够将两个对象传递给被触发的方法。我该怎么做?

到目前为止,我一直在寻找创建一个已更改的eventArgs:

 public class CompArgs : System.EventArgs
    {
    private object metode;
    private Type typen;

    public CompArgs(object m, Type t)
    {
        this.metode = m;
        this.typen = t;
    }

    public object Metode()
    {
        return metode;
    }

    public Type Typen()
    {
        return typen;
    }
}

但我该怎么用呢?是否有可能以某种方式覆盖按钮的单击事件以使用自定义事件处理程序,它将CompArgs作为参数?

private void button1_Click(object sender, EventArgs e)
        {


            Assembly assembly = Assembly.LoadFile(@"c:\components.dll");

            int counter = 0;

            foreach (Type type in assembly.GetTypes())
            {
                if (type.IsClass == true)
                {

                    Button btn = new Button();
                    btn.Location = new Point(174 + (counter * 100),10);
                    btn.Size = new Size(95, 23);
                    btn.Name = type.Name;
                    btn.Text = type.Name;
                    btn.UseVisualStyleBackColor = true;


                    this.Controls.Add(btn);

                    object obj = Activator.CreateInstance(type);

                    //I need to pass on obj and type to the btn_Click
                    btn.Click += new eventHandler(btn_Click);

                    counter++;
                }
            }
         }

我需要它的事件方法:

private void btn_Click(object sender, CompArgs ca)
        {
                MessageBox.Show((string)ca.Typen().InvokeMember("getMyName",
                             BindingFlags.Default | BindingFlags.InvokeMethod,
                             null,
                             ca.Metode(),
                             null));

        }

8 个答案:

答案 0 :(得分:49)

哇,你们这完全是困难的。无需任何自定义类或方法覆盖。在这个例子中,我只需要传递一个标签索引号。您可以指定所需的任何内容,只要您的方法期望该值类型。

button.Click += (sender, EventArgs) => { buttonNext_Click(sender, EventArgs, item.NextTabIndex); };

void buttonNext_Click(object sender, EventArgs e, int index)
    {
       //your code
    }

答案 1 :(得分:5)

您是否只需在承载按钮的表单上设置属性或成员变量,并从按钮单击事件中访问这些变量?

编辑:反馈评论后的自定义按钮类建议(与上述不一样的建议)

class MyButton : Button
{
    private Type m_TYpe;

    private object m_Object;

    public object Object
    {
        get { return m_Object; }
        set { m_Object = value; }
    }

    public Type TYpe
    {
        get { return m_TYpe; }
        set { m_TYpe = value; }
    }
}




Button1Click(object sender, EventArgs args)
{
  MyButton mb = (sender as MyButton);

  //then you can access Mb.Type
  //and  Mb.object
}

答案 2 :(得分:3)

我将创建一个新Button并覆盖OnClick方法。不是传递EventArgs,而是使用其他成员传递一个新的派生类。

在接收事件的委托上,将给定的EventArgs转换为您希望获得的派生类,或者设置一个新的事件,该事件将在按下按钮的同时触发并连接到该事件。使事情更加隐含。

示例代码:

 public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        ButtonEx b1 = new ButtonEx();
        b1.OnCustomClickEvent += new ButtonEx.OnCustomClickEventHandler(b1_OnCustomClickEvent);
    }

    void  b1_OnCustomClickEvent(object sender, ButtonEx.CustomEventArgs eventArgs)
    {
        string p1 = eventArgs.CustomProperty1;
        string p2 = eventArgs.CustomProperty2;
    }
}

public class ButtonEx : Button
{
    public class CustomEventArgs : EventArgs
    {
        public String CustomProperty1;
        public String CustomProperty2;
    }

    protected override void  OnClick(EventArgs e)
    {
        base.OnClick(e);
        if(OnCustomClickEvent != null)
        {
            OnCustomClickEvent(this, new CustomEventArgs());
        }
    }

    public event OnCustomClickEventHandler OnCustomClickEvent;
    public delegate void OnCustomClickEventHandler(object sender , CustomEventArgs eventArgs);
}

答案 3 :(得分:2)

不确定它是否存在于Winforms中,但它确实存在于WPF中:所有控件上都有一个“标记”对象,您可以将任何对象附加到该对象上。您可以保存要传递的对象,然后在事件处理程序中将其从发送方对象中读回。

private void Button_Click(object sender, RoutedEventArgs e)
{
    var note = (sender as FrameworkElement).Tag as Note;
    //Do something with note here
}

答案 4 :(得分:2)

您可以使用按钮的Tag属性。您可以从设计器属性窗口向此属性添加字符串值,然后在处理程序中将其拾取为:

    private void MyButton_Click(object sender, EventArgs e)
    {
        string tagValue = ((Button) sender).Tag;

        if(tag == "blah")
        {
            // Do something
        }
    }

答案 5 :(得分:1)

您不能将自己的自定义事件参数类用于预定义的事件处理程序签名。至少,自定义事件参数类型永远不会被任何对处理程序的默认调用使用(在按钮的情况下,它只会是类型EventArgs);你可以自己调用处理程序,传递你的自定义类型,但是,你需要有一个逻辑,以便将它从EventArgs转换回它所投射的那个。

作为一种可能的解决方案(取决于您的具体情况),请考虑使用复合类型来封装您需要的项目,与事件参数类型一样,但将所需实例保留为可在事件处理程序中使用的可访问变量或者,至少通过偶数处理程序调用的方法。

例如,定义您的类型......

public class MyType
{
    public object AccessibleItem { get; set; }
}

而且,在你的表格中......

private MyType MyTypeInstance = new MyType();

private void Button_Click(object sender, EventArgs e)
{
    //here we can set the item, if needs be...
    MyTypeInstance.AccessibleItem = new Anything();
    //or access the item to use as required...
    DoSomeMagicWithMyObject(MyTypeInstance.AccessibleItem);
}

编辑:

好的,看看你现在的代码我现在只能提供这个(它不会将项目添加到表单控件容器中,而是在Linq中使用一个变量迭代器(我认为它不赞成或只是向下) - 错了(?),但是嘿......):

    private void BuildButtonToObjectDictionary()
    {
        int counter = 0;
        var assembly = Assembly.LoadFile(@"c:\components.dll");

        var buttonToObjectDictionary = (
            from type in assembly.GetTypes()
            where type.IsClass && !type.IsAbstract
            select new
            {
                Button = new Button
                {
                    Name = type.Name,
                    Text = type.Name,
                    Size = new Size(95, 25),
                    Location = new Point(175 + (counter * 100), 10),
                    UseVisualStyleBackColor = true
                },
                Item = Activator.CreateInstance(type),
                Index = counter++
            });
    }

答案 6 :(得分:0)

需要查看更多代码才能提供更好的答案,但您可以创建一个将CompArgs作为参数的事件,并在捕获buttonEvent时触发

答案 7 :(得分:0)

如果打开yourForm.Designer.cs文件,您将看到VS自动生成的所有代码。在这里,您可以更改单击按钮时调用的方法(或添加第二种方法)。

this.yourButton.Location = new System.Drawing.Point(211, 51);
this.yourButton.Name = "yourButton";
this.yourButton.Size = new System.Drawing.Size(75, 23);
this.yourButton.TabIndex = 0;
this.yourButton.Text = "yourButton";
this.yourButton.UseVisualStyleBackColor = true;
this.yourButton.Click += new System.EventHandler(this.yourMethodHere(object1, object2);

希望这有帮助。