How do you disable Aero Snap in an application? How do you disable Aero Snap in an application? wpf wpf

How do you disable Aero Snap in an application?


I recently needed to do this to a custom, resizable ResizeMode = CanResizeWithGrip WPF window with no window decorations (no title bar and buttons). I used DragMove() to move the window, and when It is maximized by AeroSnap, the window becomes unmovable and hence locked in place.

I tried Barn Monkey's solution, which partially worked, but it would still show the AeroSnap graphic and resize the app to fullscreen size. I modified it below and now it works as expect: still resizable, but no AeroSnap at all.

void Window1_MouseDown(object sender, MouseButtonEventArgs e){    if( e.LeftButton == MouseButtonState.Pressed )    {        // this prevents win7 aerosnap        if( this.ResizeMode != System.Windows.ResizeMode.NoResize )        {            this.ResizeMode = System.Windows.ResizeMode.NoResize;            this.UpdateLayout();        }        DragMove();    }}void Window1_MouseUp( object sender, MouseButtonEventArgs e ){    if( this.ResizeMode == System.Windows.ResizeMode.NoResize )    {        // restore resize grips        this.ResizeMode = System.Windows.ResizeMode.CanResizeWithGrip;        this.UpdateLayout();    }}

EDIT:

It's been a while since I wrote this, but since people still look at this I'll update it with what I use now. I still use basically the same method for preventing edge snapping and moving my windows, but I now have them packed into custom Behavior<> classes that I can attach to a Window or UserControl. This makes them very easy to use with MVVM (I use Caliburn Micro).

The behavior classes are:

/// <summary>/// behavior that makes a window/dialog draggable by clicking anywhere /// on it that is not a control (ie, button)/// </summary>public class DragMoveBehavior<T> : Behavior<T> where T : FrameworkElement{    protected override void OnAttached()    {        AssociatedObject.MouseLeftButtonDown += MouseDown;        base.OnAttached();    }    protected override void OnDetaching()    {        AssociatedObject.MouseLeftButtonDown -= MouseDown;        base.OnDetaching();    }    void MouseDown( object sender, EventArgs ea ) => Window.GetWindow( sender as T )?.DragMove();}public class WinDragMoveBehavior : DragMoveBehavior<Window> { }public class UCDragMoveBehavior : DragMoveBehavior<UserControl> { }/// <summary>/// behavior that makes a window/dialog not resizable while clicked.  this prevents/// the window from being snapped to the edge of the screen (AeroSnap).  if DragMoveBehavior/// is also used, this must be attached first./// </summary>/// <typeparam name="T"></typeparam>public class NoSnapBehavior<T> : Behavior<T> where T : FrameworkElement{    ResizeMode lastMode = ResizeMode.NoResize;    protected override void OnAttached()    {        AssociatedObject.MouseLeftButtonDown += MouseDown;        AssociatedObject.MouseLeftButtonUp += MouseUp;        base.OnAttached();    }    protected override void OnDetaching()    {        AssociatedObject.MouseLeftButtonDown -= MouseDown;        AssociatedObject.MouseLeftButtonUp -= MouseUp;        base.OnDetaching();    }    /// <summary>    /// make it so the window can be moved by dragging    /// </summary>    void MouseDown( object sender, EventArgs ea )    {        var win = Window.GetWindow( sender as T );        if( win != null && win.ResizeMode != ResizeMode.NoResize )        {            lastMode = win.ResizeMode;            win.ResizeMode = ResizeMode.NoResize;            win.UpdateLayout();        }    }    void MouseUp( object sender, EventArgs ea )    {        var win = Window.GetWindow( sender as T );        if( win != null && win.ResizeMode != lastMode )        {            win.ResizeMode = lastMode;            win.UpdateLayout();        }    }}public class WinNoSnapBehavior : NoSnapBehavior<Window> { }public class UCNoSnapBehavior : NoSnapBehavior<UserControl> { }

I then attach them to my dialog box Views with:

<UserControl ...  xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"  xmlns:util:="...">  <i:Interaction.Behaviors>    <util:UCNoSnapBehavior/>    <util:UCDragMoveBehavior/>  </i:Interaction.Behaviors>  ...</UserControl>

And it just works!


If you are giving example of "Sticky Notes" of Win7, you may have noticed that it does NOT have standard window border. On that as a base, I can only tell you that there's no direct way of doing this except you set ResizeMode="NoResize" and handling the resize behavior manually. Following is a very basic, non-professional solution that i've quickly created to get you started, but you can append more functions if you like :)

<Window    x:Class="WpfApplication1.Window1"    x:Name="window"    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    Title="Window1"    Width="300"    Height="300"    ResizeMode="NoResize"    WindowStyle="None"    AllowsTransparency="True"    Background="Transparent"    WindowState="Maximized">    <Window.Resources>        <x:Array            x:Key="TextBlockList"            Type="{x:Type TextBlock}">            <TextBlock                Text="○ Resize Horizontally by dragging right grip" />            <TextBlock                Text="○ Resize Vertically by dragging bottom grip" />            <TextBlock                Text="○ Move Horizontally by dragging left grip" />            <TextBlock                Text="○ Move Verticallyby dragging top grip" />        </x:Array>    </Window.Resources>    <Grid>        <Grid.RowDefinitions>            <RowDefinition                Height="Auto" />            <RowDefinition                Height="{Binding Height, Mode=OneWay, ElementName=window}" />            <RowDefinition                Height="Auto" />        </Grid.RowDefinitions>        <Grid.ColumnDefinitions>            <ColumnDefinition                Width="Auto" />            <ColumnDefinition                Width="{Binding Width, Mode=OneWay, ElementName=window}" />            <ColumnDefinition                Width="Auto" />        </Grid.ColumnDefinitions>        <GridSplitter            Grid.Column="1"            Grid.Row="1"            HorizontalAlignment="Left"            MinWidth="5" />        <GridSplitter            Grid.Column="1"            Grid.Row="1"            HorizontalAlignment="Right"            MinWidth="5" />        <GridSplitter            Grid.Column="1"            Grid.Row="1"            VerticalAlignment="Top"            MinHeight="5"            ResizeDirection="Rows"            HorizontalAlignment="Stretch" />        <GridSplitter            Grid.Column="1"            Grid.Row="1"            VerticalAlignment="Bottom"            MinHeight="5"            ResizeDirection="Rows"            HorizontalAlignment="Stretch" />        <Border            Grid.Column="1"            Grid.Row="1"            Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"            Margin="5">            <Grid x:Name="root">                <ItemsControl                    ItemsSource="{StaticResource TextBlockList}" />            </Grid>        </Border>    </Grid></Window>

You can even make a control (basically a panel) that can be resized and moved within its parent canvas. Now this control can be filled into a transparent maximized window. This'll give you an illusion of your control being a window that doesn't respond to 'Window Snap' and will not dock!

Hope this helps.
Regards,
Mihir Gokani


I was using anthony's solution for awhile, but if you switch ResizeMode the window would temporary remove the sizing border, which is a little anoying. Here's another solution. By setting the WS_OVERLAPPEDWINDOW flag and removing the WS_THICKFRAME flag will disable Aero Snap feature for the window while not temporary removing the sizing border. You can play around with the styles to get the exact style you need, but key is removing the WS_THICKFRAME flag.

        public enum WindowStyles: int{    WS_BORDER = 0x00800000,    WS_CAPTION = 0x00C00000,    WS_CHILD = 0x40000000,    WS_CHILDWINDOW = 0x40000000,    WS_CLIPCHILDREN = 0x02000000,    WS_CLIPSIBLINGS = 0x04000000,    WS_DISABLED = 0x08000000,    WS_DLGFRAME = 0x00400000,    WS_GROUP = 0x00020000,    WS_HSCROLL = 0x00100000,    WS_ICONIC = 0x20000000,    WS_MAXIMIZE = 0x01000000,    WS_MAXIMIZEBOX = 0x00010000,    WS_MINIMIZE = 0x20000000,    WS_MINIMIZEBOX = 0x00020000,    WS_OVERLAPPED = 0x00000000,    WS_OVERLAPPEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,    WS_POPUP = unchecked((int)0x80000000),    WS_POPUPWINDOW = WS_POPUP | WS_BORDER | WS_SYSMENU,    WS_SIZEBOX = 0x00040000,    WS_SYSMENU = 0x00080000,    WS_TABSTOP = 0x00010000,    WS_THICKFRAME = 0x00040000,    WS_TILED = 0x00000000,    WS_TILEDWINDOW = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX,    WS_VISIBLE = 0x10000000,    WS_VSCROLL = 0x00200000,}int newWinLongStyle = 0;newWinLongStyle |= (int)WindowStyles.WS_OVERLAPPEDWINDOW;newWinLongStyle ^= (int)WindowStyles.WS_THICKFRAME; WindowInteropHelper helper = new WindowInteropHelper(this);NativeMethods.SetWindowLong(helper.Handle, (int)WindowStyles.GWL_STYLE, newWinLongStyle);