Is it possible to avoid Windows Forms namespace in WPF?

Emon Haque 3,176 Reputation points
2021-07-18T09:52:09.89+00:00

The other day I've seen my second window (runs on a different thread) opens in Primary Screen while the MainWindow is Maximised in Secondary Screen. It opens wherever the MainWindow is if the MainWindow isn't Maximized. If I use same thread and set MainWindow as its Owner and WindowStartupLocation = WindowStartupLocation.CenterOwner, it also opens wherever the MainWindow is.

To solve the issue I'd to add <UseWindowsForms>true</UseWindowsForms> in <PropertyGroup> and this if/else:

public static void Activate(string message) {
    double left, top, width, height;
    if App.Current.MainWindow.WindowState == WindowState.Maximized) {
        var screen = System.Windows.Forms.Screen.FromHandle(new System.Windows.Interop.WindowInteropHelper(App.Current.MainWindow).Handle);
        left = screen.WorkingArea.Left;
        top = screen.WorkingArea.Top;
        width = screen.WorkingArea.Width;
        height = screen.Bounds.Height;
    }
    else {
        left = App.Current.MainWindow.Left;
        top = App.Current.MainWindow.Top;
        width = App.Current.MainWindow.Width;
        height = App.Current.MainWindow.Height;
    }
    App.Current.MainWindow.IsEnabled = false;
    var thread = new Thread(() => {
        window = new BusyWindow(width, height, message) {
            Left = left,
            Top = top
        };
        window.Show();
        Dispatcher.Run();
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
}

It works BUT looks weird because I've System.Windows.Forms and <UseWindowsForms>true</UseWindowsForms> in a WPF app!

EDIT

The original issue was WindowState:

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;
    App.Current.MainWindow.IsEnabled = false;
    var thread = new Thread(() => {
        window = new BusyWindow(width, height, message) {
            Left = left,
            Top = top,
            WindowState = state
        };
        window.Show();
        Dispatcher.Run();
    });
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    IsOpened = true;
}

If I keep WindowState = state, it opens the BusyWindow in primary screen when MainWindow is maximised in secondary screen so I've removed that and got into another issue! If I maximize MainWindow in Primary/Secondary screen and hit refresh, button that opens BusyWindow, the Top/Left of BusyWindow get the old Top/Left of MainWindow in Normal State. This behavior doesn't change even if I set Top/Left in OnSourceInitialized, here you can see the problem. If I move MainWindow between screens after maximizing it's alright.

I've seen some example like this where extern method's been used to get actual Top/Left, haven't tried that yet. Is there any simpler way to fix the issue?

Windows Presentation Foundation
Windows Presentation Foundation
A part of the .NET Framework that provides a unified programming model for building line-of-business desktop applications on Windows.
2,772 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Sam of Simple Samples 5,541 Reputation points
    2021-07-18T16:57:42.183+00:00

    Sure, you do not need to use Windows Forms in WPF. If however you need to use Windows Forms in WPF then you must reference Windows Forms.

    In C# and in most languages, a namespace is just a name that qualifies things; for C# it qualifies classes. So I really do not understand what you are asking.


Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.