I've a custom window, BusyWindow, to show some animation while the app is printing document. Here's what it does:

So 1) when I click on other minimized window while the BusyWindow is there, that window comes in between the BusyWindow and MainWindow, I don't want anything in between those. 2) I can click on MainWindow in the taskbar while the BusyWindow is there and the MainWindow gets minimized, I want it to stop interacting with MainWindow while BusyWindow is there and 3) If I click other window before the SaveDialog window is shown, the SaveDialog window becomes a background window and it doesn't come to foreground even if I click on that, I want the SaveDialog window to be the Topmost when it's shown.
How to do that?
EDIT
Here's the short sample I wanted to post and Azure blocked. Have these in MainWindow.xaml.cs:
public partial class MainWindow : Window
{
public MainWindow() => InitializeComponent();
void Print(object sender, RoutedEventArgs e) {
var dialog = new PrintDialog();
if (dialog.ShowDialog() != true) return;
BusyWindow.Activate("Printing ....");
// put a sleep here on main thread to interact with other windows, I still cant write Thread[dot]Sleep, Azure blocks if I do!
var document = new FixedDocument() { Pages = { new PageContent() { Child = new FixedPage() } } };
document.DocumentPaginator.PageSize = new Size(dialog.PrintableAreaWidth, dialog.PrintableAreaHeight);
dialog.PrintDocument(document.DocumentPaginator, "");
BusyWindow.Terminate();
}
}
class BusyWindow : Window
{
Path arc;
PointAnimationUsingPath pointAnim;
BooleanAnimationUsingKeyFrames isLargeAnim;
TextBlock text;
static BusyWindow window;
public string InfoText { get; set; }
public BusyWindow(double width, double height) {
Width = width;
Height = height;
WindowStyle = WindowStyle.None;
ResizeMode = ResizeMode.NoResize;
AllowsTransparency = true;
ShowInTaskbar = false;
Topmost = true;
Background = new SolidColorBrush(Color.FromArgb(100, 0, 0, 100));
initializeContent();
initializeAnimations();
Loaded += onLoaded;
Unloaded += onUnloaded;
}
void onLoaded(object sender, RoutedEventArgs e) {
text.Text = InfoText;
var segment = (ArcSegment)((PathGeometry)arc.Data).Figures[0].Segments[0];
segment.BeginAnimation(ArcSegment.PointProperty, pointAnim);
segment.BeginAnimation(ArcSegment.IsLargeArcProperty, isLargeAnim);
}
//Unloaded doesn't have any effect here, cleanup should be done in `OnClosed`
void onUnloaded(object sender, RoutedEventArgs e) {
Loaded -= onLoaded;
Unloaded -= onUnloaded;
}
void initializeContent() {
var ellipse = new Path() {
Fill = Brushes.White,
Data = new EllipseGeometry() {
Center = new Point(Width / 2, Height / 2),
RadiusX = 150,
RadiusY = 150
}
};
arc = new Path() {
Stroke = Brushes.Coral,
StrokeThickness = 5,
Data = new PathGeometry() {
Figures = {
new PathFigure() {
StartPoint = new Point(Width / 2 + 149, Height / 2),
Segments = {
new ArcSegment() {
IsLargeArc = true,
Point = new Point(Width / 2 + 149, Height / 2 - 0.1),
Size = new Size(148,148),
SweepDirection = SweepDirection.Clockwise
}
}
}
}
}
};
text = new TextBlock() {
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
FontSize = 36,
Foreground = Brushes.Coral
};
Content = new Grid() { Children = { ellipse, text, arc } };
}
void initializeAnimations() {
pointAnim = new PointAnimationUsingPath() {
PathGeometry = PathGeometry.CreateFromGeometry(arc.Data),
Duration = TimeSpan.FromSeconds(2),
AccelerationRatio = 0.5,
DecelerationRatio = 0.5,
RepeatBehavior = RepeatBehavior.Forever
};
isLargeAnim = new BooleanAnimationUsingKeyFrames() {
KeyFrames = {
new DiscreteBooleanKeyFrame(false, TimeSpan.FromSeconds(0)),
new DiscreteBooleanKeyFrame(true, TimeSpan.FromSeconds(1)),
new DiscreteBooleanKeyFrame(false, TimeSpan.FromSeconds(2))
},
RepeatBehavior = RepeatBehavior.Forever
};
}
public static void Activate(string message) {
double left = App.Current.MainWindow.Left;
double top = App.Current.MainWindow.Top;
double width = App.Current.MainWindow.Width;
double height = App.Current.MainWindow.Height;
var state = App.Current.MainWindow.WindowState;
var thread = new Thread(() => {
window = new BusyWindow(width, height) {
Top = top,
Left = left,
WindowState = state,
InfoText = message
};
window.Show();
Dispatcher.Run();
});
thread.SetApartmentState(ApartmentState.STA);
thread.Start();
}
public static void Terminate() {
while (window == null) { }
window.Dispatcher.Invoke(window.Close);
window.Dispatcher.InvokeShutdown();
}
}
and these in MainWindow.xaml:
<Grid Margin="20">
<Button Content="Print" Click="Print"/>
</Grid>
you'll be able to see this with all those:


