1

I am making some changes to a page (by adding/removing controls) and I want to continue with my code only when the layout is settled (all elements measured and arranged etc).

How do I do this? Is there some Task I can await on that will fire when layout is complete?

(Right now using Yields and other tricks, but they all make me feel dirty)

Shahar Prish
  • 4,838
  • 3
  • 26
  • 47

1 Answers1

3

You can build a Task around any event by using TaskCompletionSource<T>.

In your case, it sounds like UIElement.LayoutUpdated may be the event you want (not entirely sure about that - WPF layout details are not my strong point).

Here's an example:

public static Task LayoutUpdatedAsync(this UIElement element)
{
  var tcs = new TaskCompletionSource<object>();
  EventHandler handler = (s, e) =>
  {
    element.LayoutUpdated -= handler;
    tcs.SetCompleted(null);
  };
  element.LayoutUpdated += handler;
  return tcs.Task;
}

Then you can use this method to await the next instance of that event:

await myUiElement.LayoutUpdatedAsync();
Stephen Cleary
  • 437,863
  • 77
  • 675
  • 810
  • 2
    LayoutUpdated doesn't seem to be enough - it can fire multiple times.. But thanks. – Shahar Prish Jan 08 '13 at 10:21
  • FYI I came up with an almost-identical solution for [a UWP question](https://stackoverflow.com/questions/47776473/how-to-create-variable-number-of-richtextboxoverflow-elements/47803012#47803012) but in that case merely waiting for the event didn't work; I had to force an also inject a dummy await to allow the UI thread to pump. – Peter Torr - MSFT Dec 18 '17 at 21:05