0

I have custom window with WindowState=WindowState.Maximized with border and thumb inside in the border, it seems that when the WindowState=WindowState.Maximized I cannot drag and move the custom window to different screen.

Xaml:

    <Window x:Class="WpfApplication3.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" 
        Height="350"
        Width="525"
        WindowStyle="None">
        <Border Name="headerBorder" 
            Width="Auto" 
            Height="50" 
            VerticalAlignment="Top"
            CornerRadius="5,5,0,0" 
            DockPanel.Dock="Top" 
            Background="Red" 
            BorderThickness="1,1,1,1"
            BorderBrush="Yellow">
            <Grid x:Name="PART_Title">
                <Thumb x:Name="headerThumb" 
                    Opacity="0" 
                    Background="{x:Null}" 
                    Foreground="{x:Null}" 
                    DragDelta="headerThumb_DragDelta"/>
            </Grid>
        </Border>
    </Window>

C#:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        WindowState = System.Windows.WindowState.Maximized;
    }

    private void headerThumb_DragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
    {
        Left = Left + e.HorizontalChange;
        Top = Top + e.VerticalChange;
    }
}

I've also overridden MouseLeftButtonDown method and using DragMove() inside but without success. I've also tried to subscribe to thumb's MouseLeftButtonDown and write there DragMove() but without success.

Max
  • 1,810
  • 3
  • 26
  • 37
David Michaeli
  • 367
  • 5
  • 26
  • 1
    Did you try to use the [WindowChrome](https://msdn.microsoft.com/en-us/library/system.windows.shell.windowchrome%28v=vs.110%29.aspx) in .NET 4.5? It allows you to have a window without any style and border and be able to manipulate it like a classic window (even in WindowState Maximized). – Max May 20 '15 at 12:28

1 Answers1

3

By default, maximized windows cannot be moved, thus Left and Top have no effect. One option would be to register to the Thumb.DragStarted event and check if the window is maximized. If yes, you can set WindowState.Normal and successively update the Left and Top properties.

In code, this would look somewhat like this:

private void Thumb_OnDragStarted(object sender, DragStartedEventArgs e)
{
    // If the window is not maximized, do nothing
    if (WindowState != WindowState.Maximized)
        return;

    // Set window state to normal
    WindowState = WindowState.Normal;

    // Here you have to determine the initial Left and Top values
    // for the window that has WindowState normal
    // I would use something like the native 'GetCursorPos' (in user32.dll)
    // function to get the absolute mouse point on all screens 
    var point = new Win32Point();
    GetCursorPos(ref point);
    Left = point - certainXValue;
    Top = point - certainYValue;

}

You can learn more about GetCursorPos here.

However, I would strongly advise you to use the WindowChrome class that comes with .NET 4.5 and that was also suggested by Max in the comments. You just have to use the following code and you have the functionality you're asking for:

<Window x:Class="ThumbMaximizedWindow.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350"
        Width="525"
        WindowStyle="None"
        WindowState="Maximized">
    <WindowChrome.WindowChrome>
        <WindowChrome />
    </WindowChrome.WindowChrome>

</Window>
Community
  • 1
  • 1
feO2x
  • 5,358
  • 2
  • 37
  • 46
  • Indeed. You can set the size of the thumb by setting the [CaptionHeight](https://msdn.microsoft.com/en-us/library/system.windows.shell.windowchrome.captionheight%28v=vs.110%29.aspx) property of the `WindowChrome`. [CornerRadius](https://msdn.microsoft.com/en-us/library/system.windows.shell.windowchrome.cornerradius%28v=vs.110%29.aspx) and [ResizeBorderThickness](https://msdn.microsoft.com/en-us/library/system.windows.shell.windowchrome.resizeborderthickness%28v=vs.110%29.aspx) are also interesting. – Max May 20 '15 at 15:47
  • I see that the app have strange behaviour, i have 2 monitors, when the app is in maximize mode and dragged to second monitor to maximize mode, the default window buttons is apprears.. its known issue? – David Michaeli Jun 01 '15 at 10:42
  • I just tried with the code above (WindowChrome) and I could not reconstruct your problem. The default buttons did not appear when I started dragging on my first monitor, moved the normal window to the next monitor and maximized it there again (all in one go). Did you apply any code that is not in the example above? – feO2x Jun 01 '15 at 16:34
  • @feO2x Do you know how to fix the window, when maximized, with the solution, the window loses about 4-5px on all sides. So the margins on all sides are incorrect when maximized. – Jason Stevenson Feb 21 '19 at 14:24
  • Also with the tag, when resizing the window, a strange flicker behavior is happening, showing a window behind my window, like the default chrome is trying to show... Any fix for that? – Jason Stevenson Feb 21 '19 at 15:01
  • @JasonStevenson I cannot recreate this problem - nothings flickering on my machines. Can you provide an [MCVE](https://stackoverflow.com/help/mcve)? – feO2x Feb 25 '19 at 09:57
  • The fix was to change the NonClientFrameEdges attribute from NONE to one of the sides. That seems to have fixed the problem. https://stackoverflow.com/questions/51669632/wpf-windowchrome-causing-flickering-on-resize – Jason Stevenson Mar 01 '19 at 00:32