事件处理程序的同步
我有一个循环:事件处理程序的同步
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完成他们的工作。我希望我明确了主要想法。感谢您的回复。
迅速解决事件处理程序代码后,移动如
void FeLayoutUpdated(object sender, EventArgs e)
{
counter++;
if(counter >= lista.Count)
DoSth();
}
是有一个原因是: -
public void Foo(List<FrameworkElement> list)
{
foreach(FrameworkElement fe in list)
{
fe.UpdateLayout();
}
DoSth();
}
不为你工作? (注意Foo应该在主UI线程上调用)。
是的。 UpdateLayout - afaik - 是异步的。因此,在DoSth()之前,我必须确保列表中的所有元素都已更新布局,例如更新多行DataGrid布局需要更多时间,因此在DataGrid完成布局更新之前将会触发DoSth()。 – 2010-08-25 12:31:33
@Michal:是什么让你觉得'UpdateLayout'是异步的? – 2010-08-25 13:52:10
Hm ...列表(在我的测试用例中)包含两个DataGrid(我称之为PrintGrids),它们放置在控件上,而不会显示给用户。用户将看到其他DataGrid(VisibleGrids)和将要打印的数据。当他按下“打印”时,PrintGrids将与来自VisibleGrids的数据一起提供。所以我必须让DataGrid.UpdateLayout让DataGrid自行刷新。而当我这样做时,我正在打印一张带有数据的DataGrid,另一张没有,因此我认为第二张在发送到打印机前没有完成刷新。 – 2010-08-25 14:12:52
请注意,不能保证'LayoutUpdated'只会触发一次'FrameworkElement' – AnthonyWJones 2010-08-25 12:19:44
我的不好。我刚刚更新了代码。正如你所看到的,我不能将DoSth()移动到事件处理程序。 – 2010-08-25 12:34:39
我想那么而不是简单的计数器,你需要跟踪是否每个元素已被更新或不,但也不会工作,因为你只想捕获最后LayoutUpdated事件。无论如何,发件人也将为空,因此跟踪更新的元素将会非常棘手。 – VinayC 2010-08-25 13:12:59