2011-01-27 57 views
14

當我點擊一個按鈕時,我需要能夠將兩個對象傳遞給正在觸發的方法。我該怎麼做呢?如何將變量傳遞給按鈕事件方法?

到目前爲止,我一直在尋找創造改變的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)); 

     } 
+0

您可以通過派生自Button類來重寫OnClick方法。已經使用這種技術添加了答案。 – Ian 2011-01-27 11:42:46

回答

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 
} 
+1

@WithithNath - 我之前使用過這種方法,但覺得這是一種不乾淨的方式。我需要按鈕來引用正確的對象,所以我上次做的方式是將對象存儲在列表中。將按鈕對象的相對索引保存在其Tag屬性中,然後在我需要時對其進行解析。 – Bildsoe 2011-01-27 11:32:00

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++ 
      }); 
    } 
+0

但我會有很多按鈕與自己的對象需要訪問。我怎樣才能做到這一點。早些時候,我將這些對象存儲在一個列表中。將按鈕對象的相對索引保存在其Tag屬性中,然後在我需要時對其進行解析。 – Bildsoe 2011-01-27 11:37:18

+0

@Bildsoe:創建實例在哪裏? IT是同樣的概念,但是你可以使用`Dictionary`,`Key`作爲一個按鈕的引用,並且與相應的`Value` - 甚至是`Hashtable`相關聯。 – 2011-01-27 11:41:13

+0

我已經包含了一些更多的代碼來向你展示我想要完成的事情。 – Bildsoe 2011-01-27 11:47:10

0

需要看到更多的代碼,以提供更好的答案,但你可以創建一個需要你CompArgs作爲參數,當buttonEvent被捕獲

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); 

希望這會有所幫助。

2

不知道這是否存在於Winforms中,但它在WPF中有效:所有控件上都有一個「標籤」對象,您可以將其附加到任何對象。您可以保存要傳遞的對象,然後在事件處理程序中將其讀回發件人對象。

private void Button_Click(object sender, RoutedEventArgs e) 
{ 
    var note = (sender as FrameworkElement).Tag as Note; 
    //Do something with note here 
} 
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); 
} 
32

哇,你們正在這完全是困難的。不需要任何自定義類或方法覆蓋。在這個例子中,我只需要傳遞一個製表索引號。你可以指定任何你想要的,只要你的方法期望值類型。

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

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

您可以使用按鈕的Tag屬性。您可以從設計器屬性窗口向此屬性添加字符串值,然後在處理程序中將其拾取,如下所示:

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

     if(tag == "blah") 
     { 
      // Do something 
     } 
    } 
相關問題