C# передача дополнительных параметров обработчику событий?


допустим, я хочу передать некоторые дополнительные данные при назначении обработчика событий. Рассмотрим следующий код:

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

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

Как бы я идти о получении данных в мой метод evHandler?

8   51  

8 ответов:

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

захваченные переменные:

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

мне было трудно понять пример @spender выше, особенно с: Object.assignHandler((sender) => evHandler(sender,someData)); потому что нет такой вещи, как Object.assignHandler в буквальном смысле. Так что я сделал немного больше гуглить и нашел . Ответ Питера Дунихо был тот, который щелкнул в моей голове (это не моя работа):

СНиП

обычный подход заключается в использовании анонимного метода с обработчиком событий это ваша измененная подпись. Для пример:

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

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

конечно, вы не должны проходить в 172, или даже сделать третий параметр в инт. :)

/ snip

используя этот пример, я смог передать два пользовательских 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 объекты, которые я не верю изменения, как работает пример). Я сейчас это выясняю.

вы можете попробовать сделать это:

string yourObject;

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

ну, самый простой метод id, чтобы сделать someData переменная-член вот так:

public class MyClass
{
    private string _eventData;

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

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

Я не уверен, что это лучшие способ сделать это, но это действительно зависит от типа события, объекта и т. д.

вы можете создать пользовательский объект, имеющий дополнительные свойства на основе Объекта:

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

Если данные больше не должны изменяться после инициализации, вы также можете добавить пользовательский конструктор, например.

вот мое однострочное решение, которое передает дополнительные параметры обработчику таймера.

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

мой вопрос, который был похож, был отмечен дубликатом, поэтому я подумал, что добавлю ответ здесь, так как он не позволит мне ответить на мой вопрос.

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