Programing

이벤트 처리기에 추가 매개 변수를 전달하는 C #?

crosscheck 2020. 12. 30. 19:01
반응형

이벤트 처리기에 추가 매개 변수를 전달하는 C #?


이벤트 핸들러를 할당 할 때 추가 데이터를 전달하고 싶습니다. 다음 코드를 고려하십시오.

private void setup(string someData)
{
     Object.assignHandler(evHandler);
}

public void evHandler(Object sender)
{
    // need someData here!!!
}

someData를 내 evHandler 메서드로 가져 오는 방법은 무엇입니까?


private void setup(string someData)
{
     Object.assignHandler((sender) => evHandler(sender,someData));
}
public void evHandler(Object sender, string someData)
{
    // need someData here!!!
}

나는 특히 위의 @spender의 예를 알아내는 데 어려움을 겪었습니다 . 문자 그대로 의미가 Object.assignHandler((sender) => evHandler(sender,someData));없기 때문 Object.assignHandler입니다. 그래서 인터넷 검색을 좀 더해서이 예제를 찾았습니다 . Peter Duniho의 대답은 내 머릿속을 클릭 한 것입니다 (이것은 내 작업이 아닙니다).

한조각

일반적인 접근 방식은 수정 된 서명이있는 이벤트 처리기와 함께 익명 메서드를 사용하는 것입니다. 예를 들면 :

void Onbutton_click(object sender, EventArgs e, int i) { ... }

button.Click += delegate(object sender, EventArgs e) 
{ Onbutton_click(sender, e, 172); };

물론 172를 전달하거나 세 번째 매개 변수를 int로 만들 필요는 없습니다. :)

/한조각

이 예제를 사용하여 람다 표기법을 사용하여 두 개의 사용자 지정 ComboBoxItem개체를 Timer.Elapsed이벤트 에 전달할 수있었습니다 .

simulatorTimer.Elapsed +=
(sender, e) => onTimedEvent(sender, e,
(ComboBoxItem) cbPressureSetting.SelectedItem,
(ComboBoxItem) cbTemperatureSetting.SelectedItem);

그런 다음 처리기로 :

static void onTimedEvent(object sender, EventArgs e, ComboBoxItem pressure, ComboBoxItem temperature)
    {
        Console.WriteLine("Requested pressure: {0} PSIA\nRequested temperature: {1}° C", pressure, temperature);
    }

이것은 위 예제의 새로운 코드는 아니지만이를 해석하는 방법을 보여줍니다. 저와 같은 누군가가 유익하고 유익하다고 생각하여 저처럼 개념을 이해하려고 시간을 소비하지 않기를 바랍니다.

이 코드는 내 프로젝트에서 ComboBoxItem작동합니다 (예제가 작동하는 방식을 변경한다고 생각하지 않는 개체 에 대한 스레드 안전 하지 않은 예외 제외 ). 나는 그것을 지금 알아 내고있다.


캡처 된 변수 :

private void setup(string someData)
{
    Object.assignHandler((sender,args) => {
        evHandler(sender, someData);
    });
}

public void evHandler(Object sender, string someData)
{
    // use someData here
}

또는 (C # 2.0 대안) :

    Object.assignHandler((EventHandler)delegate(object sender,EventArgs args) {
        evHandler(sender, someData);
    });

이 작업을 시도 할 수 있습니다.

string yourObject;

theClassWithTheEvent.myEvent += (sender, model) =>
{
 yourObject = "somthing";
}

비슷한 내 질문이 중복으로 표시되었으므로 내 질문에 대한 답변이 없으므로 여기에 답변을 추가 할 것이라고 생각했습니다.

class Program
    {
        delegate void ComponentEventHandler(params dynamic[] args);

        event ComponentEventHandler onTest;

        static void Main(string[] args)
        {  
            Program prg = new Program();

            // can be bound to event and called that way
            prg.onTest += prg.Test;
            prg.onTest.Invoke("What", 5, 12.0);

            Console.ReadKey();
        }

        public void Test(params dynamic[] values)
        {
            // assign our params to variables
            string name = values[0];
            int age = values[1];
            double value = values[2];

            Console.WriteLine(name);
            Console.WriteLine(age);
            Console.WriteLine(value);
        }
    }

Well, the simplest method id to make someData a member variable like so:

public class MyClass
{
    private string _eventData;

    private void setup(string someData) 
    {
       _eventData = someData;
       Object.assignHandler(evHandler);
    }

    public void evHandler()
    {
        // do something with _eventData here
    }
}

I'm not sure that's the best way to do it, but it really depends on the event type, the object, etc.


You could create a custom object having additional properties based on Object:

class CustomObject : Object
{
    public string SomeData;
}

private void setup(string someData)
{
    CustomObject customObject = new CustomObject { SomeData = someData };
    CustomObject.assignHandler(evHandler);
}

public void evHandler(Object sender)
{
    string someData = ((CustomObject)sender).SomeData;
}

If the data should not be changed anymore after initialization, you could also add a custom constructor, for example.


Here is my one-line solution that pass extra parameters to a timer handler.

private void OnFailed(uint errorCode, string message)
{
    ThreadPoolTimer.CreateTimer((timer) => {
    UI.ErrorMessage = string.Format("Error: 0x{0:X} {1}", errorCode, message);
    }, System.TimeSpan.FromMilliseconds(100));
}

ReferenceURL : https://stackoverflow.com/questions/4215845/c-sharp-passing-extra-parameters-to-an-event-handler

반응형