2010-08-25 111 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