Perhaps the title is worded incorrectly.
I have a "global" Busy Indicator that works great, as long as I don't try to use it when a ChildWindow is open.
I access the "global" Busy Indicator by using a static method in my App.xaml.cs:
BusyIndicator b = (BusyIndicator)App.Current.RootVisual; if (b != null) { b.BusyContent = busyText; b.IsBusy = true; }
However, if a ChildWindow is open, the BusyIndicator is always behind it.
I thought that I could set b.Content = VisualTreeHelper.GetOpenPopups().First()
, but that didn't work either.
Does anyone have any tips on having a BusyIndicator on top of open ChildWindows?
Thanks in advance.
UPDATE (SOLUTION)
Dave S sent me on the right track. It was more complicated than I had hoped, but here's my solution.
First, I had to make a full style for the ChildWindow, copying all of the Template style (left some out for post-size reasons):
<Style x:Key="MyChildWindowStyle" TargetType="gs:MyChildWindow"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="gs:MyChildWindow"> <toolkit:BusyIndicator IsBusy="{TemplateBinding IsBusy}" BusyContent="{TemplateBinding BusyContent}" BusyContentTemplate="{StaticResource MyBusyIndicatorDataTemplate}"> <Grid> <ContentPresenter x:Name="ContentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/> </Grid> </toolkit:BusyIndicator> </Style>
Then, I created my base class; notice the constructor sets the style. (Errors occurred if I tried to make it abstract.)
public class MyChildWindow : ChildWindow { public static readonly DependencyProperty IsBusyProperty = DependencyProperty.Register("IsBusy", typeof(bool), typeof(MyChildWindow), null); public static readonly DependencyProperty BusyContentProperty = DependencyProperty.Register("BusyContent", typeof(object), typeof(MyChildWindow), null); public bool IsBusy { get { return (bool)GetValue(IsBusyProperty); } set { SetValue(IsBusyProperty, value); } } public object BusyContent { get { return GetValue(BusyContentProperty); } set { SetValue(BusyContentProperty, value); } } public MyChildWindow() { this.Style = Application.Current.Resources["MyChildWindowStyle"] as Style; } }
Make sure to add a new ChildWindow, and change the <controls:ChildWindow to <gs:MyChildWindow (same with the code-behind).
Finally, update the static SetBusyIndicator method:
public static void SetBusyIndicator(string busyText, Uri busyImage) { var op = VisualTreeHelper.GetOpenPopups().Where(o => o.Child is MyChildWindow); if (op.Any()) { var bidc = new MyBusyIndicatorDataContext(busyText, busyImage); foreach (System.Windows.Controls.Primitives.Popup p in op) { var c = p.Child as MyChildWindow; c.BusyContent = bidc; c.IsBusy = true; } } else { BusyIndicator b = Current.RootVisual as BusyIndicator; if (b != null) { b.BusyContent = new MyBusyIndicatorDataContext(busyText, busyImage); b.IsBusy = true; } } }
I'm not sure this is the most efficient, but it does seem to work nicely.