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.
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:
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.