问题
I am having some troubles with the Adorner of WPF. My adorner is ok, but I don't get it displayed at the very moment I want to.
I like to do something like:
public void MyAction()
{
// property bound to the adorner VisibiltyProperty
// I like the happen a refresh now
// (code is wired correct, if I finish method here, the adorner is drawn)
this.IsAdornerEnabled = true;
try
{
... doing some long lasting things I cannot do async cause it depends on a lot of objects owned by main thread...
}
finally
{
// I like the adorner to be removed from UI now
this.IsAdornerEnabled = false;
}
}
The IsAdornerEnabled Property is correct bound to the adorner and makes a notification to it. But in this code the adorner is painted and removed for a split second when the method terminates.
How is it possible to get it rendered before the UI is thread is blocked?
Any help is very appreciated.
Explanation: I like to use the adorner to create a non-clickable, half transparent pane over my main tab with a text like "loading module" on it. While my MainThread is navigating with magellan, resolving dependencies with castle and then creating a lof of DevExpress controls, I like to show this pane. Then I remove it again. I can create the adorner, that's no problem. The adorner works in my prototyping project, where I don't do any other things.
回答1:
I found the solution for my answer. It might no be the ultra clean way, but it works for me.
ViewModel:
private void LoadUi()
{
try
{
this.IsAdornerVisible = true;
RefreshCallback();
... some long going view initialization...
}
finally
{
this.IsAdornerVisible = false;
}
}
RefreshCallback is a property of type action, set by a method in code behind of the xaml. The method set to the RefreshCallback is this one:
private void Refresh()
{
this.Dispatcher.Invoke(new Action(() => { }), DispatcherPriority.ContextIdle, null);
}
The invoke on the dispatcher with ContextIdle makes that the rendering is done before the empty action is executed. With ContextIdle this works good. Before I tried other values of DispatcherPriority, for example Render. Did not work. Now I'm happy it works and weekend can begin.
The solution I found here: Source of my solution: Update the WPF UI now: how to wait for the rendering to finish
回答2:
Try this.
public void MyAction()
{
// property bound to the adorner VisibiltyProperty
// I like the happen a refresh now
// (code is wired correct, if I finish method here, the adorner is drawn)
this.IsAdornerEnabled = true;
try
{
this.Dispatcher.Invoke( (Action)(() =>
{
// Do your work here,
this.IsAdornerEnabled = false;
}));
}catch {
}
}
来源:https://stackoverflow.com/questions/17724975/how-to-refresh-update-the-wpf-window-after-adorner-has-been-added-enabled