private static void OnBusyStateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var isBusy = (bool) e.NewValue; var wasBusy = (bool) e.OldValue; if (isBusy == wasBusy) { return; } var hostGridObject = (GetTargetVisual(d) ?? d); Debug.Assert(hostGridObject != null); var hostGrid = hostGridObject as Grid; if (hostGrid == null) { throw new InvalidCastException( string.Format( "The object being attached to must be of type {0}. Try embedding your visual inside a {0} control, and attaching the behavior to the {0} instead.", typeof(Grid).Name)); } if (isBusy) { Debug.Assert(LogicalTreeHelper.FindLogicalNode(hostGrid, "BusyIndicator") == null); var dimBackground = GetDimBackground(d); var grid = new Grid { Name = "BusyIndicator", Opacity = 0.0 }; if (dimBackground) { grid.Cursor = Cursors.Wait; grid.ForceCursor = true; InputManager.Current.PreProcessInput += OnPreProcessInput; } grid.SetBinding(FrameworkElement.WidthProperty, new Binding("ActualWidth") { Source = hostGrid }); grid.SetBinding(FrameworkElement.HeightProperty, new Binding("ActualHeight") { Source = hostGrid }); for (var i = 1; i <= 3; ++i) { grid.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star) }); grid.RowDefinitions.Add(new RowDefinition { Height = new GridLength(1, GridUnitType.Star) }); } var viewbox = new Viewbox { HorizontalAlignment = HorizontalAlignment.Center, Stretch = Stretch.Uniform, StretchDirection = StretchDirection.Both, Child = new CircularProgressBar() }; grid.SetCurrentValue(Panel.ZIndexProperty, 1000); grid.SetCurrentValue(Grid.RowSpanProperty, Math.Max(1, hostGrid.RowDefinitions.Count)); grid.SetCurrentValue(Grid.ColumnSpanProperty, Math.Max(1, hostGrid.ColumnDefinitions.Count)); if (GetAddMargins(d)) { viewbox.SetCurrentValue(Grid.RowProperty, 1); viewbox.SetCurrentValue(Grid.ColumnProperty, 1); } else { viewbox.SetCurrentValue(Grid.RowSpanProperty, 3); viewbox.SetCurrentValue(Grid.ColumnSpanProperty, 3); } viewbox.SetCurrentValue(Panel.ZIndexProperty, 1); var dimmer = new Rectangle { Name = "Dimmer", Opacity = GetDimmerOpacity(d), Fill = GetDimmerBrush(d), Visibility = (dimBackground ? Visibility.Visible : Visibility.Collapsed) }; dimmer.SetCurrentValue(Grid.RowSpanProperty, 3); dimmer.SetCurrentValue(Grid.ColumnSpanProperty, 3); dimmer.SetCurrentValue(Panel.ZIndexProperty, 0); grid.Children.Add(dimmer); grid.Children.Add(viewbox); grid.BeginAnimation(UIElement.OpacityProperty, new DoubleAnimation(1.0, GetDimTransitionDuration(d))); hostGrid.Children.Add(grid); } else { var grid = (Grid) LogicalTreeHelper.FindLogicalNode(hostGrid, "BusyIndicator"); Debug.Assert(grid != null); grid.Name = string.Empty; var fadeOutAnimation = new DoubleAnimation(0.0, GetDimTransitionDuration(d)); fadeOutAnimation.Completed += (sender, args) => OnFadeOutAnimationCompleted(d, hostGrid, grid); grid.BeginAnimation(UIElement.OpacityProperty, fadeOutAnimation); } }