2011-01-27 26 views
14

Tôi cần có khả năng truyền dọc hai đối tượng cho phương pháp được kích hoạt khi tôi nhấp vào nút. Làm thế nào để tôi làm điều này?Làm cách nào để chuyển các biến cho một phương thức sự kiện nút?

Cho đến nay tôi đã nhìn vào việc tạo ra một thay đổi 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; 
    } 
} 

Nhưng làm thế nào tôi sẽ sử dụng nó? Có thể bằng cách nào đó ghi đè lên các sự kiện nhấp chuột của nút để sử dụng một eventhandler tùy chỉnh, trong đó có CompArgs như một tham số?

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

Và sự kiện-phương pháp mà tôi cần nó:

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

     } 
+0

Bạn có thể ghi đè phương thức OnClick bằng cách lấy từ lớp Button. Đã thêm câu trả lời bằng kỹ thuật này. – Ian

Trả lời

5

Cant bạn chỉ cần thiết lập một tài sản hoặc biến thành viên trên biểu mẫu lưu trữ nút và truy cập chúng từ sự kiện nhấp vào nút?

EDIT: tùy chỉnh nút lớp gợi ý sau khi bình luận phản hồi (không giống đề nghị như trên)

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

@WraithNath - Tôi đã sử dụng cách tiếp cận này trước đây, nhưng cảm thấy đó là một cách bẩn thỉu để làm điều đó. Tôi cần các nút để tham khảo các đối tượng bên phải vì vậy cách tôi đã làm nó thời gian qua là để lưu trữ các đối tượng trong một danh sách. Đã lưu chỉ mục tương đối của đối tượng nút trong thuộc tính Thẻ của nó và sau đó phân tích cú pháp khi tôi cần nó. – Bildsoe

+0

Xin chào, Thông tin đến từ đâu mà bạn muốn chuyển vào sự kiện nhấp chuột? nó tồn tại bên trong nút điều khiển đã có trên biểu mẫu? Tôi nghĩ rằng cách duy nhất để có thể thay đổi trình xử lý nhấn nút là thực hiện điều khiển nút của riêng bạn hoặc một dẫn xuất của các cửa sổ tạo thành một. Bạn có thể lưu trữ các đối tượng bạn muốn sử dụng trong sự kiện nhấp trong thẻ của nút dưới dạng mảng hoặc loại tùy chỉnh, sau đó chỉ cần truyền người gửi dưới dạng nút và truy xuất thẻ. Nút trên biểu mẫu bật lên có người dùng chọn và tùy chọn và đóng biểu mẫu không? – WraithNath

+0

@WraithNath - Tôi đã bao gồm một số mã khác. Khái niệm bạn mô tả là cách tôi đã xử lý nó trước đó. Nhưng như tôi đã nói, nó cảm thấy một chút .. ô uế. – Bildsoe

1

Bạn không thể sử dụng riêng lớp lập luận sự kiện tùy chỉnh của bạn cho một chữ ký xử lý sự kiện được xác định trước. Ít nhất, loại đối số sự kiện tùy chỉnh sẽ không bao giờ được sử dụng bởi bất kỳ lệnh gọi mặc định nào tới trình xử lý (chỉ bao gồm loại EventArgs trong trường hợp nút); bạn có thể, có khả năng, gọi cho người xử lý, chuyển loại tùy chỉnh của bạn, tuy nhiên, bạn sẽ cần phải có logic để đưa nó trở lại từ một số EventArgs vào nó mà nó đã được đúc từ đó. Là một giải pháp có thể (tùy thuộc vào tình huống của bạn), hãy xem xét một loại hỗn hợp để đóng gói các mục bạn yêu cầu, như với loại đối số sự kiện của bạn, nhưng giữ trường hợp cần thiết như một biến truy cập có thể được sử dụng từ bên trong sự kiện xử lý, hoặc, ít nhất, bằng các phương thức/s mà trình xử lý thậm chí gọi.

Ví dụ, xác định loại của bạn ...

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

Và, trong lớp học mẫu của bạn ...

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

EDIT:

Được rồi, nhìn vào mã tôi hiện tại của bạn chỉ có thể cung cấp cho bạn điều này ngay bây giờ (nó không thêm các mục vào thùng chứa kiểm soát biểu mẫu và nó sử dụng một trình biến đổi biến trong LINQ (mà tôi nghĩ là bị nhăn mặt hoặc chỉ xuống sai (?), nhưng này .. .):

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

Nhưng tôi sẽ có rất nhiều nút với các đối tượng riêng của họ cần phải được truy cập. Tôi có thể làm cái này như thế nào. Trước đó tôi đã lưu trữ các đối tượng trong một danh sách. Đã lưu chỉ mục tương đối của đối tượng nút trong thuộc tính Thẻ của nó và sau đó phân tích cú pháp khi tôi cần nó. – Bildsoe

+0

@Bildsoe: Các cá thể được tạo ở đâu? Đó là khái niệm tương tự, nhưng bạn có thể sử dụng 'Dictionary', nhờ đó mà' Key' tham chiếu đến một nút và được kết hợp với 'Giá trị' thích hợp - hoặc thậm chí là' Hashtable'. –

+0

Tôi đã bao gồm một số mã khác để cho bạn thấy những gì tôi đang cố gắng hoàn thành. – Bildsoe

0

sẽ cần phải nhìn thấy nhiều mã để đưa ra một câu trả lời tốt hơn, nhưng bạn có thể tạo ra một sự kiện diễn CompArgs của bạn như một tham số và được phát sinh khi buttonEvent được chụp

0

Nếu file bạn mở yourForm.Designer.cs bạn sẽ thấy tất cả các ô tô mã được tạo bởi VS. Ở đây bạn có thể thay đổi phương thức được gọi khi nhấp vào nút (hoặc thêm phương thức thứ hai).

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

Hy vọng điều này sẽ hữu ích.

+0

là điều này có thể? không phải là người gửi và eventArgs allways thông qua như các tham số? – Bildsoe

+1

Theo như tôi thấy, điều này sẽ không hoạt động chút nào. Và ngay cả khi nó đã làm, nó sẽ luôn là hai đối số được chỉ định như tham số, thay vì được gọi và các đối số được chỉ định cho mỗi lời gọi.Và nếu điều đó xảy ra là hành vi mong muốn, nó vẫn sẽ không biên dịch, do thiếu dấu ngoặc đơn. –

2

Không chắc chắn nếu điều này tồn tại trong Winforms nhưng nó trong WPF: Có một "thẻ" đối tượng trên tất cả các điều khiển mà bạn có thể đính kèm bất kỳ đối tượng.Bạn có thể lưu đối tượng mà bạn muốn truyền và sau đó trong trình xử lý sự kiện, hãy đọc nó ra khỏi đối tượng người gửi.

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

Tương tự như vậy đối với Winforms – flq

+1

Nó không phải là một cách rất thanh lịch mặc dù. Bạn phải biết về Thẻ và những gì mong đợi trong đó. – Ian

3

Tôi muốn tạo nút mới và ghi đè phương pháp OnClick. Thay vì truyền xuống EventArgs, hãy vượt qua một lớp dẫn xuất mới với các thành viên bổ sung của bạn. Trên đại biểu nhận sự kiện, hãy đưa EventArgs đã cho vào lớp được thừa kế hơn mà bạn mong đợi nhận được, cách khác thiết lập một Sự kiện mới sẽ được kích hoạt cùng lúc khi nút được nhấn và kết nối với nút đó thay vào đó để làm cho mọi thứ trở nên ngầm hơn.

Ví dụ Code:

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

câu trả lời rất hay –

32

Wow, các cậu đang làm điều này hoàn toàn đến khó. Không cần cho bất kỳ lớp tùy chỉnh hoặc ghi đè phương thức nào. Trong ví dụ này, tôi chỉ cần chuyển một số chỉ mục tab. Bạn có thể chỉ định bất cứ điều gì bạn muốn, miễn là phương pháp của bạn đang mong đợi loại giá trị đó.

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

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

Không chắc tại sao mọi người không chỉ sử dụng câu trả lời này. Đơn giản hơn rất nhiều. – Larry

+0

Xa hơn thanh lịch và nạc hơn là bắt nguồn từ lớp kiểm soát. –

+1

Xin chào các bạn, tôi biết đây là một bài đăng cũ hơn nhưng tôi nghĩ rằng tôi sẽ chỉ ra rằng nếu bạn plop một biến trong mã trên VS sẽ ném một phù hợp. Tôi có một nút mà tôi muốn gửi một switcher trên keypress, tôi sử dụng mã trên (mà là tuyệt vời) nhưng nó không giống như biến boolean ... đây là chữ ký phương thức: 'private void UpdateDBButton_Click (object sender, EventArgs e , bool fullReset) 'và dòng xử lý sự kiện:' UpdateDBButton.Click + = (người gửi, EventArgs) => {bool fullReset = false; UpdateDBButton_Click (người gửi, EventArgs, fullReset); }; ' –

1

Bạn có thể sử dụng thuộc tính Tag của nút. Bạn có thể thêm một giá trị chuỗi vào thuộc tính này từ cửa sổ thuộc tính thiết kế và sau đó chọn nó trong bộ xử lý như sau:

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

     if(tag == "blah") 
     { 
      // Do something 
     } 
    } 
Các vấn đề liên quan