2011-01-27 13 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

답변

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

@WraithNath - 전에이 방법을 사용해 왔지만 그것을하는 것이 더러운 방법이라고 느낍니다. 마지막으로 한 방법으로 목록에 개체를 저장하는 것이므로 올바른 개체를 참조하는 데 단추가 필요합니다. Button 객체의 상대 인덱스를 Tag 속성에 저장 한 다음 필요할 때 파싱했습니다. – Bildsoe

+0

안녕하세요, 클릭 이벤트에 전달하려는 정보의 위치는 어디입니까? 이미 폼에있는 버튼 컨트롤 안에 있습니까? 단추 클릭 처리기를 변경할 수있는 유일한 방법은 고유 한 단추 컨트롤 또는 Windows 양식의 파생물을 구현하는 것입니다. 버튼의 태그에서 click 이벤트에 사용할 객체를 배열 또는 사용자 정의 유형으로 저장 한 다음 보낸 사람을 버튼으로 캐스팅하고 태그를 검색 할 수 있습니다. 사용자가 옵션을 선택하고 옵션을 닫고 양식을 닫는 팝업 양식의 버튼입니까? – WraithNath

+0

@WraithNath - 몇 가지 코드를 추가했습니다. 당신이 묘사하는 개념은 내가 그것을 어떻게 일찍 처리했는지입니다. 하지만 내가 말했듯이, 그것은 약간 부정하다고 느낍니다. – Bildsoe

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

편집 :

좋아, 당신의 현재 코드 I보고 당신에게 단지 이것을 제공 할 수 있습니다 (그것은 폼 컨트롤 컨테이너에 아이템을 추가하지 않고 Linq 내에서 변수 iterator를 사용합니다 (이것은 내가 싫어하는 것 같아요, 아니면 오른쪽 아래에 잘못된 것 (?)),하지만 헤이 .. .) :

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

하지만 액세스 할 필요가있는 객체가있는 많은 버튼이 있습니다. 어떻게해야합니까? 이전에 나는 목록에 객체를 저장했다. Button 객체의 상대 인덱스를 Tag 속성에 저장 한 다음 필요할 때 파싱했습니다. – Bildsoe

+0

@Bildsoe : 인스턴스는 어디에 생성됩니까? IT는 같은 종류의 개념이지만 'Key'는 버튼에 대한 참조이며 적절한 'Value'또는 'Hashtable'과 연결되어있는 'Dictionary'를 사용할 수 있습니다. –

+0

나는 내가 성취하려는 것을 보여주기 위해 좀 더 많은 코드를 포함시켰다. – Bildsoe

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

희망이 도움이됩니다.

+0

이 가능합니까? 보낸 사람이 아니며 eventArgs가 항상 매개 변수로 전달 되었습니까? – Bildsoe

+1

내가 볼 수있는 한, 이것은 전혀 작동하지 않습니다. 그리고 그렇게하더라도, 호출되는 것이 아니라 매개 변수로 지정된 두 개의 인수와 호출마다 지정된 인수가 항상 동일합니다.그리고 그 일이 원하는 행동으로 일어난다면, 괄호가 없어서 여전히 컴파일되지 않을 것입니다. –

2

Winforms에는 존재하지만 WPF에서는 없는지 확실하지 않습니다. 개체를 연결할 수있는 모든 컨트롤에 "태그"개체가 있습니다.전달할 객체를 저장 한 다음 이벤트 핸들러에서 보낸 객체에서 다시 읽습니다.

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

Winforms 동일하게 간다 – flq

+1

아주 우아한 방식은 아니지만. 당신은 태그에 대해 알아야하고 그것에 무엇을 기대해야합니다. – Ian

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

아주 좋은 대답 –

32

와우는, 너희들은 어려운 전적으로이하고 있습니다. 모든 사용자 정의 클래스 또는 메소드 대체가 필요 없습니다. 이 예제에서는 탭 인덱스 번호 만 전달하면됩니다. 메소드가 값 유형을 예상하는 한 원하는 것을 지정할 수 있습니다.

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

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

사람들이 왜이 대답을 사용하지 않는지 잘 모르겠습니다. 훨씬 더 간단합니다. – Larry

+0

컨트롤 클래스에서 파생되는 것보다 훨씬 우아하고 부담이 적습니다. –

+1

이봐, 얘들 아, 나는 이것이 더 오래된 포스트라는 것을 알고있다. 그러나 나는 당신이 VS 위의 코드에서 변수를 올리면 (자), 그 코드가 적합할지 어떨지를 지적 할 것이라고 생각했다. 나는 keypress에 스위처를 보내고 싶었고, 위의 코드를 사용했다. (위대하다.)하지만 부울 변수처럼 didnt한다 ... 이것은 메소드 서명이다 : private void UpdateDBButton_Click (Object sender, EventArgs e , bool fullReset)'및 이벤트 핸들러 행 :'UpdateDBButton.Click + = (sender, EventArgs) => {bool fullReset = false; UpdateDBButton_Click (sender, EventArgs, fullReset); };' –

1

버튼의 Tag 속성을 사용할 수 있습니다. 디자이너 속성 창에서이 속성에 문자열 값을 추가 한 다음 처리기에서 다음과 같이 문자열 값을 가져올 수 있습니다.

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

     if(tag == "blah") 
     { 
      // Do something 
     } 
    } 
관련 문제