2010-08-25 124 views
2

我有一個循環:事件處理程序的同步

List<FrameworkElement> list; 
public void Foo(object sender, PrintPageEventArgs e) 
{ 
    foreach(FrameworkElement fe in list) 
    { 
    fe.LayoutUpdated += FeLayoutUpdated; 
    fe.UpdateLayout(); 
    } 
    if(counter >= lista.Count) 
    e.PageVisual = objectFromClass. // was DoSth() 
} 
int counter = 0; 
void FeLayoutUpdated(object sender, EventArgs e) 
{ 
    counter++ 
} 

所以我需要DoSth()總是被解僱時富()被觸發,當從列表中的所有FrameworkElement的對象都將有它的佈局更新。我試圖使用一些Thread類和BackgroundWorker,但是我無法達到所需的行爲,這是主線程正在等待fe.UpdateLayout完成他們的工作。我希望我明確了主要想法。感謝您的回覆。

回答

1

迅速解決事件處理程序代碼後,移動如

void FeLayoutUpdated(object sender, EventArgs e) 
{ 
    counter++; 
    if(counter >= lista.Count) 
    DoSth(); 
} 
+0

請注意,不能保證'LayoutUpdated'只會觸發一次'FrameworkElement' – AnthonyWJones 2010-08-25 12:19:44

+0

我的不好。我剛剛更新了代碼。正如你所看到的,我不能將DoSth()移動到事件處理程序。 – 2010-08-25 12:34:39

+0

我想那麼而不是簡單的計數器,你需要跟蹤是否每個元素已被更新或不,但也不會工作,因爲你只想捕獲最後LayoutUpdated事件。無論如何,發件人也將爲空,因此跟蹤更新的元素將會非常棘手。 – VinayC 2010-08-25 13:12:59

1

是有一個原因是: -

public void Foo(List<FrameworkElement> list) 
{ 
    foreach(FrameworkElement fe in list) 
    { 
    fe.UpdateLayout(); 
    } 
    DoSth(); 
} 

不爲你工作? (注意Foo應該在主UI線程上調用)。

+0

是的。 UpdateLayout - afaik - 是異步的。因此,在DoSth()之前,我必須確保列表中的所有元素都已更新佈局,例如更新多行DataGrid佈局需要更多時間,因此在DataGrid完成佈局更新之前將會觸發DoSth()。 – 2010-08-25 12:31:33

+0

@Michal:是什麼讓你覺得'UpdateLayout'是異步的? – 2010-08-25 13:52:10

+0

Hm ...列表(在我的測試用例中)包含兩個DataGrid(我稱之爲PrintGrids),它們放置在控件上,而不會顯示給用戶。用戶將看到其他DataGrid(VisibleGrids)和將要打印的數據。當他按下「打印」時,PrintGrids將與來自VisibleGrids的數據一起提供。所以我必須讓DataGrid.UpdateLayout讓DataGrid自行刷新。而當我這樣做時,我正在打印一張帶有數據的DataGrid,另一張沒有,因此我認爲第二張在發送到打印機前沒有完成刷新。 – 2010-08-25 14:12:52