Click here to Skip to main content
15,867,308 members
Articles / Desktop Programming / WPF

Moving a WPF Window with a WindowStyle of None

Rate me:
Please Sign up or sign in to vote.
4.00/5 (7 votes)
14 Apr 2010CC (Attr 3U)2 min read 93.9K   23   1
How to move a WPF Window with a WindowStyle of None

CustomWindow

In my previous post: Creating a Custom Window Style, I showed how to create a custom Style in WPF using WindowStyle.None and ResizeMode.NoResize. What bugged me about this approach was that you can't move the custom window, because you have no Window chrome to drag around the screen.

I read one article that took a really “hard core” approach and used interop to use the SendMessage, ReleaseCapture, and MouseMove methods, but this is a very Win32-oriented approach and in actual fact, WPF provides a much easier approach.

To enable a user to move your window from any area on that window (not necessarily just the title if you want to do something really different), you simply handle the MouseLeftButtonDown event for a UIElement on your window and call the DragMove method, as shown in the following code example:

C#
private void title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    DragMove();
}

Hooking it Up to the Style

Having defined the look-and-feel in a reusable Style, we need a way of hooking up the MouseLeftButtonDown event and handling it in our Window class. Unfortunately, this is a little bit tricky. If the Style is defined in the XAML that defines your Window, then you can simply add the event handler for the relevant UIElement as you would for any other element. However, putting your Style in with your actual Window doesn't give you a very reusable Style. Instead, give a fixed name to the element in your Style, such as PART_Title, and then get a reference to that element and hook the event in your Window class. Are you still with me?

The following XAML code example shows the named part in the Window Style.

XML
<style targettype=""{x:Type" type="text/css" window="" x:key=""MessageBox"">...
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type Window}">
                <Border Background="{DynamicResource MessageBoxBackgroundBrush}"
                        BorderBrush="{DynamicResource MessageBoxBorderBrush}"
                        BorderThickness="1">
                    <Grid>
                        <Grid.RowDefinitions>
                            <RowDefinition Height="30" />
                            <RowDefinition />
                        </Grid.RowDefinitions>
                        <Grid x:Name="PART_Title">
                            <Grid.Background>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#FF214F18" Offset="0"/>
                                    <GradientStop Color="#FF20361C" Offset="1"/>
                                </LinearGradientBrush>
                            </Grid.Background>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition />
                                <ColumnDefinition Width="30" />
                            </Grid.ColumnDefinitions>
                            <Label Style="{DynamicResource MessageBoxTitle}" 
				Content="{TemplateBinding Title}" />
                            <Button x:Name="PART_Close"
                                    Content="{DynamicResource CloseButtonPath}"
                                    Grid.Column="1"
                                    Style="{DynamicResource CloseButton}"
                                    Padding="4" />
                        </Grid>
                        <AdornerDecorator Grid.Row="1">
                            <ContentPresenter Content="{TemplateBinding Content}" 
				Margin="{TemplateBinding Margin}" />
                        </AdornerDecorator>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter></style>

All I've done from the previous version of the Style is to add an x:Name attribute with a value of PART_Title to the Grid that contains the title of the Window.

The following code example shows how to get a reference to that element and hook the mouse event in the CustomMessageBox class.

C#
namespace CustomWindow
{
    /// <summary>
    /// Interaction logic for CustomMessageBox.xaml
    /// </summary>
    public partial class CustomMessageBox : Window
    {
        private MessageBoxResult _result = MessageBoxResult.None;
        private Button _close;
        private FrameworkElement _title;

        ...

        private void this_Loaded(object sender, RoutedEventArgs e)
        {
            this._close = (Button)this.Template.FindName("PART_Close", this);
            if (null != this._close)
            {
                if (false == this._cancel.IsVisible)
                {
                    this._close.IsCancel = false;
                }
            }

            this._title = (FrameworkElement)this.Template.FindName("PART_Title", this);
            if (null != this._title)
            {
                this._title.MouseLeftButtonDown += 
		new MouseButtonEventHandler(title_MouseLeftButtonDown);
            }
        }

        private void title_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DragMove();
        }

        ...
    }
}

Summary

So, if you want to enable window movement for custom styled windows, then you need to call the DragMove method from an event handler for the MouseLeftButtonDown event. In this example, the CustomMessageBox class provides that event handling. If you are using a Style that applies to multiple windows, then you will need to hook the mouse event in each class, or implement a base class that provides this functionality for you and inherit from that class.

As before, I've provided the (now updated) source code for the custom message box class.

This work is licensed under a Creative Commons Attribution By license.

License

This article, along with any associated source code and files, is licensed under The Creative Commons Attribution 3.0 Unported License


Written By
Software Developer (Senior)
United Kingdom United Kingdom
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions

 
GeneralVery useful Pin
BGW5-Sep-13 20:48
BGW5-Sep-13 20:48 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.