2012-12-28 91 views
3

我試圖創建一個方法,它需要委託作爲其參數之一,但它不工作。我究竟做錯了什麼?我得到錯誤「回調是一個變量,但像一種方法使用」在windowAnimation.Completed += new EventHandler(callback)的線上。將委託作爲參數的方法?

private void animateWindowWidth(Window window, double width, double duration, Delegate callback) 
{ 
    window.BeginInit(); 
    window.Dispatcher.BeginInvoke(new Action(() => 
    { 
     DoubleAnimation windowAnimation = new DoubleAnimation(); 
     windowAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration)); 
     windowAnimation.From = window.Width; 
     windowAnimation.To = width; 
     windowAnimation.FillBehavior = FillBehavior.HoldEnd; 
     windowAnimation.Completed += new EventHandler(callback); 
     window.BeginAnimation(Window.WidthProperty, windowAnimation); 
    }), null); 
    window.EndInit(); 
} 
+0

讓我建議一個更優雅的語法(imo):Dispatcher.BeginInvoke((Action)(()=> {});' – abatishchev

+0

謝謝。有什麼不同?它只是一個捷徑, – Aaron

+0

據我所知,沒有什麼區別,只是一個味道的問題,正如我從開始強調:) – abatishchev

回答

2

我只是想我會解釋一下爲什麼Delegate本身不窩RK。

Delegate不是真正的代表,而是一個代表。它基本上是一個擁有委託的變量。這就是爲什麼給一個變量像方法一樣給出錯誤的原因。

一個簡單的例子(授予你可能永遠不會這樣做)是如果你有兩個代表做添加。一個用ints,另一個用浮動。您可以存儲代表在Delegate對象,並傳遞給一個變量調用DynamicInvoke()另一個功能:

void MyMethod(Delegate d) 
    { 
     d.DynamicInvoke(leftHandSide, rightHandSide); 
    } 

沒有這兩個代表存儲在Delegate對象的事,你會得到相應的功能。

在你的情況下,windowAnimation.Completed正在期待一個實際的委託方法,如EventHandler。另外,EventHandler的構造函數需要一個委託方法。因此在任何情況下使用Delegate對象都不起作用。

你必須包裝在一個委託或使用lambda功能將真正的方法調用

windowAnimation.Completed += (s,e) => callback.DynamicInvoke(); 

或更改callbackEventHandler,並創建一個新的時,當你想調用這種方法。

+0

謝謝!這涵蓋了我想知道的一切,現在我明白了爲什麼我的方法不起作用的原因。 – Aaron

0

你可以在你的方法簽名更改爲:

private void animateWindowWidth(
    Window window, 
    double width, 
    double duration, 
    EventHandler callback) 

,並導致錯誤到

windowAnimation.Completed += callback; 

該行然後創建一個新EvenHandler,當你調用該方法。

+0

謝謝,這是有效的。以我的方式做到這一點是不可能的? – Aaron

0

嘗試使用Action代替Delegate和替換字符串:

windowAnimation.Completed += new EventHandler(callback); 

與此:

windowAnimation.Completed += (s, e) => callback(); 

那麼,到底應該是這樣的:

private void animateWindowWidth(Window window, double width, double duration, Action callback) 
{ 
    window.BeginInit(); 
    window.Dispatcher.BeginInvoke(new Action(() => 
    { 
     DoubleAnimation windowAnimation = new DoubleAnimation(); 
     windowAnimation.Duration = new Duration(TimeSpan.FromSeconds(duration)); 
     windowAnimation.From = window.Width; 
     windowAnimation.To = width; 
     windowAnimation.FillBehavior = FillBehavior.HoldEnd; 
     windowAnimation.Completed += (s, e) => callback()); 
     window.BeginAnimation(Window.WidthProperty, windowAnimation); 
    }), null); 
    window.EndInit(); 
} 
+0

謝謝,但那不適合我。我得到「只有賦值,調用,遞增,遞減,等待和新的對象表達式可以用作語句」作爲錯誤。 – Aaron

+0

謝爾蓋五,你編譯它?至少你應該寫'windowAnimation.Completed + =(s,e)=> callback.DynamicInvoke(s,e);'。但爲什麼會這樣做添加一個簡單的事件處理程序? – horgh

+0

對不起,我沒有編譯它)。爲了使它工作,只需用Action替換Delegate。 –