假設我想在分配事件處理函數時傳遞一些額外的數據。考慮下面的代碼:C#將額外的參數傳遞給事件處理程序?
private void setup(string someData)
{
Object.assignHandler(evHandler);
}
public void evHandler(Object sender)
{
// need someData here!!!
}
我該如何去獲取someData到我的evHandler方法?
假設我想在分配事件處理函數時傳遞一些額外的數據。考慮下面的代碼: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!!!
}
好,最簡單的方法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
}
}
我不知道那是最好方式做到這一點,但它確實取決於事件類型,對象等
在想這個方法,但是可能會使用不同的someData調用多次setup。該數據應該對每個處理程序都是唯一的。 – 2010-11-18 14:39:38
在這種情況下,spender或Marc的解決方案好得多 – CodingGorilla 2010-11-18 14:42:12
捕獲變量:
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);
});
被捕獲變量===閉包? – Matt 2010-11-18 14:39:31
@Matt - 是的,捕獲的變量是詞法關閉。 – 2010-11-18 14:40:29
澄清,是第一個對C#.NET 2.0無效的解決方案嗎? – 2010-11-18 14:43:36
你可以試試這樣做:
string yourObject;
theClassWithTheEvent.myEvent += (sender, model) =>
{
yourObject = "somthing";
}
基於對象,您可以創建具有附加屬性的自定義對象:
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;
}
如果數據不能再修改例如,在初始化之後,您還可以添加自定義構造函數。
我很難搞清@ spender上面的例子,特別是:Object.assignHandler((sender) => evHandler(sender,someData));
,因爲在字面意義上沒有Object.assignHandler
這樣的東西。所以我多做了一點Google搜索,發現this example。彼得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
事件使用lambda符號:
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);
}
這不是上述示例中的任何新代碼,但它確實證明了h解釋他們。希望像我這樣的人發現它很有用,所以他們不會像我一樣花費數小時來理解概念。
這段代碼在我的項目中工作(除了一個非線程安全的例外,我不相信這個例子會改變這個例子的工作方式)。我正在弄清楚這一點。
這是我的單線解決方案,它將額外的參數傳遞給定時器處理程序。
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);
}
}
我在這個問題上多標準解決方案,第一個答案http://stackoverflow.com/questions/14058412/passing-parameter-to-an-event-handler/14058441#14058441 – 2013-11-25 14:09:34