views:

51

answers:

2

I have a loop:

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++
}

So I need DoSth() to be fired always when Foo() is fired and when all FrameworkElement objects from list will have it's Layout updated. I was trying to use some Thread class and also BackgroundWorker, but I couldn't reach desired behaviour, which is that main Thread is waiting for fe.UpdateLayout's to finish their jobs. I hope I made the main idea clear. Thanks for replies.

+1  A: 

A quick solution to move after code in event handler such as

void FeLayoutUpdated(object sender, EventArgs e)
{
  counter++;
  if(counter >= lista.Count)
    DoSth();
}
VinayC
Note there is no guarantee that `LayoutUpdated` only fires once per `FrameworkElement`
AnthonyWJones
My bad. I've just updated the code. As you can see I cannot move DoSth() to event handler.
Michal Krawiec
I guess then instead of simple counter, you need to track if each element has been updated or not but that also won't work as you would like to capture the last LayoutUpdated event only. Regardless, sender will also be null so tracking updated elements would be tricky.
VinayC
+1  A: 

Is there a reason why this:-

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

Doesn't work for you? (Note Foo should be called on the main UI thread).

AnthonyWJones
Yes there is. UpdateLayout - afaik - is async. So before DoSth() I have to be sure that all elements on the list have Layouts updated and for example updating layout of DataGrid with many rows takes more time, hence DoSth() will be fired before the DataGrid finishes updating it's Layout.
Michal Krawiec
@Michal: What makes you think `UpdateLayout` is async?
Brian Gideon
Hm... list (in my test case) contains two DataGrids (I call them PrintGrids), which are placed on a control, which is not displayed to a user. User sees other DataGrids (VisibleGrids) with data that will be printed. When he presses 'Print' PrintGrids are feed with data from VisibleGrids. So I have to make DataGrid.UpdateLayout to ask DataGrid to refresh itself. And when I do it in above way, I am getting on a printed sheet one DataGrid with data and the other one without, hence I think the second one does not finish refreshing before beeing send to printer.
Michal Krawiec
@Michal: Can you update your question with some code with the printing operation? If you have not explicitly created threads, called into the `ThreadPool`, called `BeginInvoke` on a delegate, etc. then it is unlikely there is async problem here.
Brian Gideon
@Brian - I don't know which part of code do you need. This is all I have connected with printing operation. I do not explicitly create any threads, I do not call into the ThreadPool, I do not use BackgroundWorker. It's just plaing UpdateLayout.
Michal Krawiec