Welcome to Pete Brown's 10rem.net

First time here? If you are a developer or are interested in Microsoft tools and technology, please consider subscribing to the latest posts.

You may also be interested in my blog archives, the articles section, or some of my lab projects such as the C64 emulator written in Silverlight.

(hide this)

Moving a WPF Window with Custom Chrome

Pete Brown - 01 February 2010

Robert Iagar on twitter asked how to move a window in WPF without using the built-in title bar or resorting to user32.dll, so I whipped up this quick sample.

image

So let’s have at it:

Window Xaml

We’ll create a simple window with no built-in border or titlebar. We’ll use a border, some shapes and a HeaderedContentControl to provide stand-in titlebar/content areas.

<Window x:Class="WpfWindowMoveSample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        WindowStyle='None'
        AllowsTransparency='True'
        Background='Transparent'
        Title=''
        Height='350'
        Width='525'>
    <Grid>
        <Border Background='Beige'
                BorderBrush='LightBlue'
                BorderThickness='2'
                CornerRadius='10'
                Padding='5'>
            <HeaderedContentControl>
                <!-- New Title Bar -->
                <HeaderedContentControl.Header>
                    
                    <!-- If you want to move using something else, wire up the event there instead -->
                    <Grid MouseDown='OnDragMoveWindow'>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width='*' />
                            <ColumnDefinition Width='Auto' />
                        </Grid.ColumnDefinitions>

                        <Rectangle Grid.ColumnSpan='2'
                                   Fill='LightBlue' />

                        <TextBlock Grid.Column='0'
                                   FontSize='15'
                                   FontWeight='Bold'
                                   VerticalAlignment='Center'
                                   Margin='3'
                                   Text='This is my custom title bar' />
                        <Button x:Name='WindowCloseButton'
                                Grid.Column='1'
                                Width='25'
                                Height='25'
                                Cursor='Hand'
                                Margin='3'
                                VerticalAlignment='Center'
                                Click='WindowCloseButton_Click'
                                Content='X' />
                    </Grid>
                </HeaderedContentControl.Header>
                
                <!-- New Content Area -->
                <HeaderedContentControl.Content>
                    <Grid Margin='3'>
                        <TextBlock Text='Content goes here...' />
                    </Grid>
                </HeaderedContentControl.Content>
            </HeaderedContentControl>
        </Border>
    </Grid>
</Window>

The main line of interest in this window is wiring up the OnDragMoveWindow handler to the MouseDown event of our titlebar grid.

The resulting Window looks like this:

Don't hate me because I'm beautiful

You can’t move it yet, because we haven’t wired up the event handlers. You’ll also have a hard time closing it since we don’t have the close handler wired up.

Code-Behind

Next we need to wire up the event handler to allow for moving the window around.

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private void WindowCloseButton_Click(object sender, RoutedEventArgs e)
    {
        Close();
    }

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

Note you can also use a command like ApplicationCommands.Close rather than working with an event handler for close. If you’re writing a real application, I suggest you take that route.

That’s all there is to it. If you want to have something else responsible for dragging the window, you simply wire up the DragMove to the MouseDown on that control.

One gotcha has to do with the space the OS normally allocates for the title bar. You’ll notice this if you try and dock the window in Windows 7. The API to address that takes a bit more work, so I’ll address it in a later post.

     
posted by Pete Brown on Monday, February 1, 2010
filed under:      

9 comments for “Moving a WPF Window with Custom Chrome”

  1. Pete Brownsays:
    @Robert

    Yep, you can wire right to the grid as well. I'd recommend wiring to the outside border though, as it works best if you go with the outermost visible thing.

    Either way, try it out. Glad it worked for you.

    Pete
  2. Jeremiah Morrillsays:
    Great post! In most situations I've had, I have not had much luck with the DragMove(...) method call. It will block the UI thread up to a second if you click and do not move your mouse after the DragMove(...) call. This might be upsetting to a user if your application is playing a video or running an animation.
  3. Juan Medinasays:
    I have to agree about the DragMove blocking being an issue. It makes it hard to perform any animations or other UI work once the DragMove kicks in. I have personally found out that handling the move with a Thumb control on the custom window template gives better (and more controllable) results.
  4. Maxxxsays:
    Nice & simples.

    I'm trying to do this with a WPF app for a touch enabled device - and DragMove doesn't work (because the DragMove code checks for the mouse button being down, I believe)

    Any idea how to handle touch-dragging? (And pinch window resizing would be good, too :))
  5. Crystalsays:
    I didn't see this mentioned in the article, but if you want to click and drag from anywhere (instead of a particular UI control), you can also just override the OnMouseLeftButtonDown method. :)

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
    base.OnMouseLeftButtonDown(e);
    this.DragMove();
    }

    WPF is amazing.

Comment on this Post

Remember me

1 trackback for “Moving a WPF Window with Custom Chrome”

  1. uberVU - social commentssays:
    This post was mentioned on Twitter by Pete_Brown: Blogged: Especially for @cellblade : Moving a WPF Window with Custom Chrome http://bit.ly/aq73VH #wpf