Continue WPF Child Window Implementation. In chapter 1, we had implemented customize child window. In this chapter, we are going to implement moving action for child window.
To achieve this goals, we would need to use Thumb control, which provided by framework.
1. We only need to change the style in App.xaml
<Application x:Class="TestApp.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml"
xmlns:common="clr-namespace:TestApp">
<Application.Resources>
<Style x:Key="ChildWindowStyle" TargetType="{x:Type common:LayoutControl}">
<Setter Property="BorderBrush" Value="Silver"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Height" Value="300"/>
<Setter Property="Width" Value="400"/>
<Setter Property="Margin" Value="20"/>
<Setter Property="Background" Value="#FFE6E6E6"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type common:LayoutControl}">
<Border BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--Make window has shadow-->
<Rectangle Fill="{TemplateBinding Background}" Grid.RowSpan="2">
<Rectangle.Effect>
<DropShadowEffect BlurRadius="10" ShadowDepth="3"/>
</Rectangle.Effect>
</Rectangle>
<!--Title bar-->
<Grid Grid.Row="0" Background="{TemplateBinding BorderBrush}">
<TextBlock Text="{TemplateBinding Title}" HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Thumb Name="moveThumb" Opacity="0"/>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<!--Minimum button-->
<Button Name="mininumBtn" Content="⚊" BorderThickness="0" Background="Transparent"/>
<!--Maximum button-->
<Button Name="maxinumBtn" Content="⬒" Margin="3,0" BorderThickness="0"
Background="Transparent"/>
<!--Close button-->
<Button Name="closeBtn" Content="✖" Margin="0,0,3,0" BorderThickness="0"
Foreground="Red" Background="Transparent"/>
</StackPanel>
</Grid>
<ContentPresenter Grid.Row="1"/>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
</Application>
2. Then we update code in LayoutControl.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
namespace TestApp
{
public class LayoutControl : UserControl
{
public static readonly DependencyProperty TitleProperty = DependencyProperty.Register(
"Title",
typeof(string),
typeof(LayoutControl),
new PropertyMetadata("My Window"));
public string Title
{
get { return (string)this.GetValue(TitleProperty); }
set { this.SetValue(TitleProperty, value); }
}
public LayoutControl()
: base()
{
this.Style = (Style)Application.Current.Resources["ChildWindowStyle"];
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
#region Title Buttons
Button btnClose = this.Template.FindName("closeBtn", this) as Button;
Button btnMaxi = this.Template.FindName("maxinumBtn", this) as Button;
Button btnMini = this.Template.FindName("mininumBtn", this) as Button;
// Close event
if (btnClose != null)
{
btnClose.Click += (s, e) => ((Panel)this.Parent).Children.Remove(this);
}
// Maxinum event
if (btnMaxi != null)
{
btnMaxi.Click += (s, e) =>
{
Panel parent = (Panel)this.Parent;
this.Margin = new Thickness(0);
this.Height = parent.ActualHeight;
this.Width = parent.ActualWidth;
};
}
// Mininum event
if (btnMini != null)
{
btnMini.Click += (s, e) =>
{
this.Visibility = Visibility.Collapsed;
};
}
#endregion
#region Move and Resize
Thumb moveThumb = this.Template.FindName("moveThumb", this) as Thumb;
if (moveThumb != null)
{
moveThumb.DragDelta += (s, e) =>
{
double left = double.IsNaN(Canvas.GetLeft(this)) ? 0 : Canvas.GetLeft(this);
double top = double.IsNaN(Canvas.GetTop(this)) ? 0 : Canvas.GetTop(this);
Canvas.SetLeft(this, left + e.HorizontalChange);
Canvas.SetTop(this, top + e.VerticalChange);
};
}
#endregion
}
}
}
Then run this app, we can move child window now. If you don't want you window moving out of stage, you can set canvas in MainWindow ClipToBounds="True"
Move