Подтвердить что ты не робот

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

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

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

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

Как я могу получить некоторые данные в моем методе evHandler?

4b9b3361

Ответ 1

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

Ответ 2

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

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

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

Или (вариант С# 2.0):

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

Ответ 3

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

надрез

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

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

Ответ 4

вы можете попробовать:

string yourObject;

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

Ответ 5

Ну, простейший идентификатор метода, чтобы сделать 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
    }
}

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

Ответ 6

Вы можете создать пользовательский объект, имеющий дополнительные свойства на основе 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;
}

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

Ответ 7

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

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

Ответ 8

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

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