8

As I understand it the dispatcher takes place in another thread, which takes care of updating data bindings, layout, etc. However, is there any way to wait until the dispatcher has no more items or at least no more data bindings? I want to ensure that the property change has updated all of its components and run the dependent property changed callbacks before running more code.

edit: so I am guessing that this is not needed, I am just trying to understand what I should have done instead. My main question is at WPF if the children of a scrollviewer resize, will the scrollviewer automatically update its extent?

but I was also curious whether i could wait for bindings to update or if there is even any guarantee that one binding updates before another? Am I expected to code such that the order of binding updates do not matter? currently I used dependency property changed callback's that perform various stuff that is often dependent on other properties updating

Community
  • 1
  • 1
James Joshua Street
  • 3,259
  • 10
  • 42
  • 80
  • 2
    Can you describe why this is necessary? It shouldn't be, and likely there exists a better way to accomplish what you'd actually like to do. – user7116 Aug 23 '13 at 19:33
  • 4
    You may want to take a look at `Dispatcher.BeginInvoke()`, most precisely the overload that accepts a `DispatcherPriority`. – Federico Berasategui Aug 23 '13 at 19:44
  • 1
    I recall writing [an answer](http://stackoverflow.com/a/16217573/302677) about the sequence of events in WPF when something loads. You might find it helpful. But HighCore's suggestion to use the Dispatcher is probably what you're looking for. (Also, the Dispatcher references the main UI thread, and it has the ability to run code at different priority levels on that thread. It's not really a separate thread) – Rachel Aug 23 '13 at 20:21
  • Did you try calling an empty action in _Dispacher.Invoke_? sth like this: _Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.Render, null);_ – Ramin Aug 24 '13 at 08:33
  • Does this answer your question? [Where is the Application.DoEvents() in WPF?](https://stackoverflow.com/questions/4502037/where-is-the-application-doevents-in-wpf) – StayOnTarget Mar 03 '21 at 18:39

1 Answers1

9

The dispatcher has several priorities for processing the single tasks. I'm quite sure you cannot change the priority of the callbacks of dependency properties. If they were changed by data binding, they will be in queue with DispatcherPriority.DataBinding priority. You manipulate the values of some dependency properties which would cause layout/other dependency properties to change. And you want to wait after your first manipulation until these layout updates/changes are processed and then do something with the current UI state?

WinForms had the DoEvents function for such cases which causes all UI events being processed before normal code execution continues. WPF has no such builtin function but you can write your own DoEvents:

public static void DoEvents()
{
  if (Application.Current == null)
    return;
  Application.Current.Dispatcher.Invoke(DispatcherPriority.Background, (Delegate) (() => {}));
}

The empty delegate is invoked synchronously, that means the call returns after the delegate was executed by the dispatcher. The DispatcherPriority.Background is a very low priority so that this dispatcher call is processed after for example data bindings, layout updates or rendering. http://msdn.microsoft.com/en-us/library/system.windows.threading.dispatcherpriority.aspx

So call DoEvents() after your first manipulation of the dependency properties and before you want to read other dependency properties and it should be done.

Torben Schramme
  • 2,104
  • 1
  • 16
  • 28
  • I get `CS1660 Cannot convert lambda expression to type 'Delegate' because it is not a delegate type` – Scott Solmer Apr 14 '20 at 19:06
  • Thanks for the answer, great idea! A little bit modified: Application.Current.Dispatcher.Invoke(()=> { }, System.Windows.Threading.DispatcherPriority.Background); – Andrey Burykin Oct 09 '20 at 12:51