Wpf因其提供样式、模板等多种方式,可以为控件的外观进行定制,因此很多Wpf教材上都说Wpf自定义控件在Wpf编程中的地位已不再有WinForm编程中那么的重要。但是在一个大的项目开发中,自定义控件还是非常的重要,依然是项目的开发、维护的基础。本人通过编写一些WPF自定义控件,来学习WPF编程,感受WPF开发的快乐与其魅力,特写系列文章--WPF自定义控件那些事,希望能对WPF的初学者一些帮助。
自定义窗口
自定义窗口,实现窗口圆角,当然在此基础上也可以是非规则的窗口,自定义的窗口标题栏,回车键转换焦点,按住鼠标左键,移动窗口位置等。以下是效果图。

一、 在自定义控件之前,先将一些要用到的画刷、颜色等可以共享的资源保存到一个公共资源字典中。
ZbShared.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<!--文本框边框-->
<Thickness x:Key="TextBoxBorderThickness">1</Thickness>
<!--文本框获取焦点时边框-->
<Thickness x:Key="TextBoxBorderFocusedThickness">2</Thickness>
<!--文本框内空-->
<Thickness x:Key="TextBoxPadding">4,3,4,3</Thickness>
<!--文本框边框弧度-->
<CornerRadius x:Key="TextBoxBorderCornerRadius">4</CornerRadius>
<!--文本框边框默认画刷-->
<SolidColorBrush x:Key="TextBoxBorderDefaultBrush" Color="Blue"></SolidColorBrush>
<!--文本框边框获取焦点时画刷-->
<SolidColorBrush x:Key="TextBoxBorderFocusedBrush"
Color="BlueViolet"></SolidColorBrush>
<Color x:Key="TextBoxBorderFocusedColor">#FF0000FF</Color>
<!--文本框边框鼠标进入时画刷-->
<SolidColorBrush x:Key="TextBoxBorderMouseOverBrush"
Color="Green"></SolidColorBrush>
<Color x:Key="TextBoxBorderMouseOverColor">#FFFF0000</Color>
<!--文本框背景-->
<SolidColorBrush x:Key="TextBoxBackground">#FFFFFFFF</SolidColorBrush>
<!--文本框边框禁用时画刷-->
<SolidColorBrush x:Key="TextBoxBorderDisabledBrush"
Color="Gray"></SolidColorBrush>
<!--文本框禁用时背景画刷-->
<SolidColorBrush x:Key="TextBoxBorderDisabledBackBrush"
Color="#FFC5CBF9"></SolidColorBrush>
<Color x:Key="TextBoxBorderDisabledBackColor">#FFC5CBF9</Color>
<!--文本框只读时背景画刷-->
<SolidColorBrush x:Key="TextBoxBorderReadOnlyBackBrush"
Color="#FFE8EDF9"></SolidColorBrush>
<Color x:Key="TextBoxBorderReadOnlyBackColor">#FFE8EDF9</Color>
<!--文本框文字前景色-->
<SolidColorBrush x:Key="TextBoxForeground" Color="Black"></SolidColorBrush>
<!--文本框禁用时文字前景色-->
<SolidColorBrush x:Key="TextBoxDisabledForeground"
Color="White"></SolidColorBrush>
<!--文本框提示文本前景色-->
<SolidColorBrush x:Key="TextBoxPromptForeground"
Color="Black"></SolidColorBrush>
<!--窗口背景画刷-->
<LinearGradientBrush x:Key="WindowBackBrush" EndPoint="0,1"
StartPoint="0,0">
<GradientStop Color="#FFDDDDDD"
Offset="0" />
<GradientStop Color="White"
Offset="1" />
</LinearGradientBrush>
<!--按钮背景画刷-->
<LinearGradientBrush x:Key="ButtonBackBrush" EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Color="#FFDCEFE3"
Offset="0" />
<GradientStop Color="#FF1360BA"
Offset="1" />
</LinearGradientBrush>
<!--边框颜色-->
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="BorderLightColor">#FFCCCCCC</Color>
<Color x:Key="BorderMediumColor">#FF888888</Color>
<Color x:Key="BorderDarkColor">#FF444444</Color>
<Color x:Key="PressedBorderLightColor">#FF888888</Color>
<Color x:Key="PressedBorderDarkColor">#FF444444</Color>
<Color x:Key="DisabledBorderLightColor">#FFAAAAAA</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="DisabledBorderDarkColor">#FF888888</Color>
<Color x:Key="FocusedBorderLightColor">#FF0000FF</Color>
<Color x:Key="FocusedBorderDarkColor">#FF0000FF</Color>
<Color x:Key="FocusedBorderDarkColor">#FF0000FF</Color>
<Color x:Key="DefaultBorderBrushDarkColor">Black</Color>
<!--面板颜色-->
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<LinearGradientBrush x:Key="WindowBackground"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0"
Color="{StaticResource WindowColor}"/>
<GradientStop Offset="1"
Color="#AAFFFFFF"/>
</LinearGradientBrush>
<Color x:Key="WindowColor">#FFE8EDF9</Color>
<LinearGradientBrush x:Key="WindowBackground"
EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0"
Color="{StaticResource WindowColor}"/>
<GradientStop Offset="1"
Color="#AAFFFFFF"/>
</LinearGradientBrush>
<Color x:Key="ContentAreaColorLight">#FFC5CBF9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="ContentAreaColorDark">#FF7381F9</Color>
<Color x:Key="DisabledControlLightColor">#FFE8EDF9</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="DisabledControlDarkColor">#FFC5CBF9</Color>
<Color x:Key="DisabledForegroundColor">#FF888888</Color>
<Color x:Key="SelectedBackgroundColor">#FFC5CBF9</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="SelectedUnfocusedColor">#FFDDDDDD</Color>
<Color x:Key="ControlLightColor">White</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMediumColor">#FF7381F9</Color>
<Color x:Key="ControlDarkColor">#FF211AA9</Color>
<Color x:Key="ControlMouseOverColor">#FF3843C4</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="ControlPressedColor">#FF211AA9</Color>
<Color x:Key="GlyphColor">#FF444444</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<Color x:Key="GlyphMouseOver">sc#1, 0.004391443, 0.002428215, 0.242281124</Color>
<!--按钮边框-->
<Thickness x:Key="ButtonBorderThickness">2</Thickness>
<Thickness x:Key="ButtonPadding">4</Thickness>
<CornerRadius x:Key="ButtonCornerRadius">4</CornerRadius>
<Color x:Key="ButtonFocuseForeColor">red</Color>
<Thickness x:Key="ButtonBorderThickness">2</Thickness>
<Thickness x:Key="ButtonPadding">4</Thickness>
<CornerRadius x:Key="ButtonCornerRadius">4</CornerRadius>
<Color x:Key="ButtonFocuseForeColor">red</Color>
<!--窗口标题按钮背景画刷-->
<LinearGradientBrush x:Key="WindowButtonBorderBackground" EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
<Color x:Key="WindowButtonBorderBackgroundFocuse">#FF0B1AFD</Color>
<!--窗口标题按钮边框画刷-->
<LinearGradientBrush x:Key="WindowButtonBorder" EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
<Color x:Key="WindowButtonBorderFocuse">#FF071CCA</Color>
<!--窗口标题按钮禁用时为透明-->
<Color x:Key="WindowButtonDisabled">#00FFFFFF</Color>
<!--窗口标题按钮变化动画-->
<Storyboard x:Key="WindowButtonStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource WindowButtonBorderBackgroundFocuse}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource WindowButtonBorderFocuse}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
<LinearGradientBrush x:Key="WindowButtonBorderBackground" EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
<Color x:Key="WindowButtonBorderBackgroundFocuse">#FF0B1AFD</Color>
<!--窗口标题按钮边框画刷-->
<LinearGradientBrush x:Key="WindowButtonBorder" EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
<Color x:Key="WindowButtonBorderFocuse">#FF071CCA</Color>
<!--窗口标题按钮禁用时为透明-->
<Color x:Key="WindowButtonDisabled">#00FFFFFF</Color>
<!--窗口标题按钮变化动画-->
<Storyboard x:Key="WindowButtonStory">
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource WindowButtonBorderBackgroundFocuse}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[0].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource WindowButtonBorderFocuse}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
<Storyboard x:Key="ButtonFocus" RepeatBehavior="Forever">
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(LinearGradientBrush.StartPoint)"
Storyboard.TargetName="Border">
<EasingPointKeyFrame KeyTime="0:0:2"
Value="0,0">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
<EasingPointKeyFrame KeyTime="0:0:4"
Value="0.5,0">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(LinearGradientBrush.EndPoint)"
Storyboard.TargetName="Border">
<EasingPointKeyFrame KeyTime="0:0:2"
Value="0.5,1">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
<EasingPointKeyFrame KeyTime="0:0:4"
Value="0.5,1">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
</PointAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0:0:2"
Value="#FFF9F473">
<EasingColorKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut" />
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
<EasingColorKeyFrame KeyTime="0:0:4"
Value="#FF7381F9">
<EasingColorKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn" />
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(LinearGradientBrush.StartPoint)"
Storyboard.TargetName="Border">
<EasingPointKeyFrame KeyTime="0:0:2"
Value="0,0">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
<EasingPointKeyFrame KeyTime="0:0:4"
Value="0.5,0">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
</PointAnimationUsingKeyFrames>
<PointAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(LinearGradientBrush.EndPoint)"
Storyboard.TargetName="Border">
<EasingPointKeyFrame KeyTime="0:0:2"
Value="0.5,1">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
<EasingPointKeyFrame KeyTime="0:0:4"
Value="0.5,1">
<EasingPointKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn" />
</EasingPointKeyFrame.EasingFunction>
</EasingPointKeyFrame>
</PointAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(GradientBrush.GradientStops)[1].(GradientStop.Color)"
Storyboard.TargetName="Border">
<EasingColorKeyFrame KeyTime="0:0:2"
Value="#FFF9F473">
<EasingColorKeyFrame.EasingFunction>
<BackEase EasingMode="EaseOut" />
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
<EasingColorKeyFrame KeyTime="0:0:4"
Value="#FF7381F9">
<EasingColorKeyFrame.EasingFunction>
<BackEase EasingMode="EaseIn" />
</EasingColorKeyFrame.EasingFunction>
</EasingColorKeyFrame>
</ColorAnimationUsingKeyFrames>
</Storyboard>
<LinearGradientBrush x:Key="MessageBackground" EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0"
Color="#AAFFFFFF" />
<GradientStop Offset="1"
Color="#44FFFFFF" />
</LinearGradientBrush>
StartPoint="0.5,0">
<GradientStop Offset="0"
Color="#AAFFFFFF" />
<GradientStop Offset="1"
Color="#44FFFFFF" />
</LinearGradientBrush>
</ResourceDictionary>
二、 自定义窗口标题栏控件
ZbWindowTitle.xaml
<UserControl x:Class="Zbsoft.WpfControls.ZbWindowTitle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="25" d:DesignWidth="100">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbButtonWindowTitle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="25"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="25"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image VerticalAlignment="Center" MaxHeight="20" MaxWidth="20" Grid.Column="1" Stretch="Uniform" Source="{Binding Path=Icon, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"></Image>
<TextBlock Margin="4,0" Grid.Column="2" VerticalAlignment="Center"
Text="{Binding Path=Title,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"></TextBlock>
<Button Style="{StaticResource ZbButtonWindowTitle}"
Name="minButton"
Grid.Column="3"
HorizontalAlignment="Left"
Width="25"
ToolTip="最小化"
Click="minButton_Click">
<Path Data="M200,229 L265,229"
Fill="Black"
StrokeThickness="3"
HorizontalAlignment="Center"
Stretch="Fill"
Stroke="#FF444444"
Height="10"
Width="16" />
</Button>
<Button Grid.Column="4"
Name="MaxButton"
ToolTip="最大化"
Style="{StaticResource ZbButtonWindowTitle}"
Click="Button_Click"
Visibility="{Binding Path=CanMax,RelativeSource={RelativeSource AncestorType=UserControl}}">
<Path Data="M9.5,16.5 L9.5,25.5 18.5,25.5 18.5,16.5 z M0.5,6.8330005 L8.3333334,6.8330005 17.897838,6.8330005 27.333334,7.0000004 27.333334,27.5 27.5,27.5 27.5,27.666335 27.5,33.833001 0.5,33.833001 z M8.5000001,0.5 L35.5,0.5 35.5,27.5 27.5,27.5 27.5,6.8330005 17.897838,6.8330005 8.5000001,6.6666669 z"
Height="14"
Stretch="Fill"
StrokeThickness="2"
Stroke="#FF444444"
Width="14" />
</Button>
<Button Grid.Column="5"
ToolTip="关闭"
Name="CloseButton"
Style="{StaticResource ZbButtonWindowTitle}"
Click="CloseButton_Click">
<Path Data="M18.5,1 L22.5,1 22.5,18.5 40,18.5 40,22.5 22.5,22.5 22.5,40 18.5,40 18.5,22.5 1,22.5 1,18.5 18.5,18.5 z"
Fill="Black"
HorizontalAlignment="Left"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="#FF444444"
StrokeThickness="2"
VerticalAlignment="Top">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="135" />
<TranslateTransform />
</TransformGroup>
</Path.RenderTransform>
</Path>
</Button>
</Grid>
</UserControl>
隐藏代码文件:ZbwindowTitle.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
二、 自定义窗口标题栏控件
ZbWindowTitle.xaml
<UserControl x:Class="Zbsoft.WpfControls.ZbWindowTitle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
mc:Ignorable="d"
d:DesignHeight="25" d:DesignWidth="100">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbButtonWindowTitle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</UserControl.Resources>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="5"></ColumnDefinition>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
<ColumnDefinition Width="25"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
<ColumnDefinition Width="25"></ColumnDefinition>
<ColumnDefinition Width="5"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image VerticalAlignment="Center" MaxHeight="20" MaxWidth="20" Grid.Column="1" Stretch="Uniform" Source="{Binding Path=Icon, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"></Image>
<TextBlock Margin="4,0" Grid.Column="2" VerticalAlignment="Center"
Text="{Binding Path=Title,RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"></TextBlock>
<Button Style="{StaticResource ZbButtonWindowTitle}"
Name="minButton"
Grid.Column="3"
HorizontalAlignment="Left"
Width="25"
ToolTip="最小化"
Click="minButton_Click">
<Path Data="M200,229 L265,229"
Fill="Black"
StrokeThickness="3"
HorizontalAlignment="Center"
Stretch="Fill"
Stroke="#FF444444"
Height="10"
Width="16" />
</Button>
<Button Grid.Column="4"
Name="MaxButton"
ToolTip="最大化"
Style="{StaticResource ZbButtonWindowTitle}"
Click="Button_Click"
Visibility="{Binding Path=CanMax,RelativeSource={RelativeSource AncestorType=UserControl}}">
<Path Data="M9.5,16.5 L9.5,25.5 18.5,25.5 18.5,16.5 z M0.5,6.8330005 L8.3333334,6.8330005 17.897838,6.8330005 27.333334,7.0000004 27.333334,27.5 27.5,27.5 27.5,27.666335 27.5,33.833001 0.5,33.833001 z M8.5000001,0.5 L35.5,0.5 35.5,27.5 27.5,27.5 27.5,6.8330005 17.897838,6.8330005 8.5000001,6.6666669 z"
Height="14"
Stretch="Fill"
StrokeThickness="2"
Stroke="#FF444444"
Width="14" />
</Button>
<Button Grid.Column="5"
ToolTip="关闭"
Name="CloseButton"
Style="{StaticResource ZbButtonWindowTitle}"
Click="CloseButton_Click">
<Path Data="M18.5,1 L22.5,1 22.5,18.5 40,18.5 40,22.5 22.5,22.5 22.5,40 18.5,40 18.5,22.5 1,22.5 1,18.5 18.5,18.5 z"
Fill="Black"
HorizontalAlignment="Left"
RenderTransformOrigin="0.5,0.5"
Stretch="Fill"
Stroke="#FF444444"
StrokeThickness="2"
VerticalAlignment="Top">
<Path.RenderTransform>
<TransformGroup>
<ScaleTransform />
<SkewTransform />
<RotateTransform Angle="135" />
<TranslateTransform />
</TransformGroup>
</Path.RenderTransform>
</Path>
</Button>
</Grid>
</UserControl>
隐藏代码文件:ZbwindowTitle.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace Zbsoft.WpfControls
{
/// <summary>
/// WindowTitle.xaml 的交互逻辑
/// </summary>
public partial class ZbWindowTitle : UserControl
{
public static DependencyProperty CanMaxProperty = DependencyProperty.Register("CanMax",
typeof(Visibility), typeof(ZbWindowTitle));
{
/// <summary>
/// WindowTitle.xaml 的交互逻辑
/// </summary>
public partial class ZbWindowTitle : UserControl
{
public static DependencyProperty CanMaxProperty = DependencyProperty.Register("CanMax",
typeof(Visibility), typeof(ZbWindowTitle));
/// <summary>
/// 是否可以最大化
/// </summary>
public Visibility CanMax
{
get { return (Visibility)GetValue(CanMaxProperty); }
set { SetValue(CanMaxProperty, value); }
}
/// 是否可以最大化
/// </summary>
public Visibility CanMax
{
get { return (Visibility)GetValue(CanMaxProperty); }
set { SetValue(CanMaxProperty, value); }
}
public static DependencyProperty TitleProperty = DependencyProperty.Register("Title",
typeof(string), typeof(ZbWindowTitle));
/// <summary>
/// 窗口标题
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static DependencyProperty IconProperty = DependencyProperty.Register("Icon",
typeof(ImageSource), typeof(ZbWindowTitle));
/// <summary>
/// 窗口标题图标
/// </summary>
public ImageSource Icon
{
get { return (ImageSource)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
typeof(string), typeof(ZbWindowTitle));
/// <summary>
/// 窗口标题
/// </summary>
public string Title
{
get { return (string)GetValue(TitleProperty); }
set { SetValue(TitleProperty, value); }
}
public static DependencyProperty IconProperty = DependencyProperty.Register("Icon",
typeof(ImageSource), typeof(ZbWindowTitle));
/// <summary>
/// 窗口标题图标
/// </summary>
public ImageSource Icon
{
get { return (ImageSource)GetValue(IconProperty); }
set { SetValue(IconProperty, value); }
}
public ZbWindowTitle()
{
InitializeComponent();
}
/// <summary>
/// 关闭按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(this);
if (w != null)
w.Close();
}
/// <summary>
/// 最小化按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void minButton_Click(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(this);
if (w != null)
w.WindowState = WindowState.Minimized;
}
/// <summary>
/// 最大化按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(this);
if (w != null)
if (w.WindowState == WindowState.Maximized)
w.WindowState = WindowState.Normal;
else
w.WindowState = WindowState.Maximized;
}
}
}
窗口标题栏按钮样式文件:ZbButtonWindowTitle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Zbsoft.WpfControls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbShared.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<!--按钮样式-->
<!-- FocusVisual -->
{
InitializeComponent();
}
/// <summary>
/// 关闭按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void CloseButton_Click(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(this);
if (w != null)
w.Close();
}
/// <summary>
/// 最小化按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void minButton_Click(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(this);
if (w != null)
w.WindowState = WindowState.Minimized;
}
/// <summary>
/// 最大化按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void Button_Click(object sender, RoutedEventArgs e)
{
Window w = Window.GetWindow(this);
if (w != null)
if (w.WindowState == WindowState.Maximized)
w.WindowState = WindowState.Normal;
else
w.WindowState = WindowState.Maximized;
}
}
}
窗口标题栏按钮样式文件:ZbButtonWindowTitle.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Zbsoft.WpfControls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbShared.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<!--按钮样式-->
<!-- FocusVisual -->
<Style x:Key="WindowButtonFocusVisual">
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<!--<Rectangle Margin="3"
RadiusX="3"
RadiusY="3"
StrokeThickness="1"
Stroke="#FFFF0000" />-->
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Setter Property="Control.Template">
<Setter.Value>
<ControlTemplate>
<Border>
<!--<Rectangle Margin="3"
RadiusX="3"
RadiusY="3"
StrokeThickness="1"
Stroke="#FFFF0000" />-->
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Button -->
<Style x:Key="ZbButtonWindowTitle" TargetType="Button">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource WindowButtonFocusVisual}" />
<Setter Property="Padding"
Value="{StaticResource ButtonPadding}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border TextBlock.Foreground="{TemplateBinding Foreground}"
x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{StaticResource WindowButtonBorder}"
>
<Style x:Key="ZbButtonWindowTitle" TargetType="Button">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{StaticResource WindowButtonFocusVisual}" />
<Setter Property="Padding"
Value="{StaticResource ButtonPadding}"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border TextBlock.Foreground="{TemplateBinding Foreground}"
x:Name="Border"
BorderThickness="{TemplateBinding BorderThickness}"
BorderBrush="{StaticResource WindowButtonBorder}"
>
<Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
</Border.Background>
<LinearGradientBrush EndPoint="0.5,1"
StartPoint="0.5,0">
<GradientStop Offset="0" />
<GradientStop Offset="1" />
</LinearGradientBrush>
</Border.Background>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5" />
<VisualTransition GeneratedDuration="0"
To="Pressed" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver"
Storyboard="{StaticResource WindowButtonStory}">
</VisualState>
<VisualState x:Name="Pressed"
Storyboard="{StaticResource WindowButtonStory}">
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Unfocused" />
<VisualState x:Name="Focused"
Storyboard="{StaticResource WindowButtonStory}">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefault"
Value="true">
<Setter TargetName="Border"
Property="BorderBrush"
Value="{StaticResource WindowButtonBorder}">
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.5" />
<VisualTransition GeneratedDuration="0"
To="Pressed" />
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver"
Storyboard="{StaticResource WindowButtonStory}">
</VisualState>
<VisualState x:Name="Pressed"
Storyboard="{StaticResource WindowButtonStory}">
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Unfocused" />
<VisualState x:Name="Focused"
Storyboard="{StaticResource WindowButtonStory}">
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="Center"
RecognizesAccessKey="True" />
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsDefault"
Value="true">
<Setter TargetName="Border"
Property="BorderBrush"
Value="{StaticResource WindowButtonBorder}">
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
三、自定义窗口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Zbsoft.WpfControls
{
/// <summary>
/// 窗口类
/// </summary>
public class ZbWindow : Window
{
/// <summary>
/// 窗口能否最大化
/// </summary>
public static DependencyProperty CanMaxProperty = DependencyProperty.Register("CanMax",
typeof(Visibility), typeof(ZbWindow));
/// <summary>
/// 窗口能否最大化
/// </summary>
public Visibility CanMax
{
get { return (Visibility)GetValue(CanMaxProperty); }
set { SetValue(CanMaxProperty, value); }
}
{
/// <summary>
/// 窗口类
/// </summary>
public class ZbWindow : Window
{
/// <summary>
/// 窗口能否最大化
/// </summary>
public static DependencyProperty CanMaxProperty = DependencyProperty.Register("CanMax",
typeof(Visibility), typeof(ZbWindow));
/// <summary>
/// 窗口能否最大化
/// </summary>
public Visibility CanMax
{
get { return (Visibility)GetValue(CanMaxProperty); }
set { SetValue(CanMaxProperty, value); }
}
/// <summary>
/// 初始化时,设置样式,并添加事件处理响应回车键到下一个控件
/// </summary>
/// <param name="e"></param>
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.Resources.MergedDictionaries.Add(new ResourceDictionary()
{
Source = new Uri("/Zbsoft.WpfControls;component/Resources/ZbWindow.xaml", UriKind.Relative)
}
);
this.Style = (Style)this.FindResource("Window");
this.KeyDown += ZbExternt.EnterKeyToNext;
this.MouseMove += new System.Windows.Input.MouseEventHandler(ZbWindow_MouseMove);
}
/// <summary>
/// 移动窗口位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ZbWindow_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed
&& (e.Source as Window != null || e.Source as System.Windows.Controls.Grid != null))
this.DragMove();
}
}
}
ZbWindow.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Zbsoft.WpfControls">
/// 初始化时,设置样式,并添加事件处理响应回车键到下一个控件
/// </summary>
/// <param name="e"></param>
protected override void OnInitialized(EventArgs e)
{
base.OnInitialized(e);
this.Resources.MergedDictionaries.Add(new ResourceDictionary()
{
Source = new Uri("/Zbsoft.WpfControls;component/Resources/ZbWindow.xaml", UriKind.Relative)
}
);
this.Style = (Style)this.FindResource("Window");
this.KeyDown += ZbExternt.EnterKeyToNext;
this.MouseMove += new System.Windows.Input.MouseEventHandler(ZbWindow_MouseMove);
}
/// <summary>
/// 移动窗口位置
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void ZbWindow_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
if (e.LeftButton == System.Windows.Input.MouseButtonState.Pressed
&& (e.Source as Window != null || e.Source as System.Windows.Controls.Grid != null))
this.DragMove();
}
}
}
ZbWindow.xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Zbsoft.WpfControls">
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbShared.xaml" />
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbButtonWindowTitle.xaml" />
</ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbShared.xaml" />
<ResourceDictionary Source="/Zbsoft.WpfControls;component/Resources/ZbButtonWindowTitle.xaml" />
</ResourceDictionary.MergedDictionaries>
<!--<SnippetWindow>-->
<Style x:Key="Window" TargetType="{x:Type local:ZbWindow}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="WindowStyle"
Value="None"></Setter>
<Setter Property="ResizeMode"
Value="NoResize"></Setter>
<Setter Property="CanMax"
Value="Collapsed"></Setter>
<!--设置此属性才能将窗口背景设透明的效果-->
<Setter Property="AllowsTransparency"
Value="True"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ZbWindow}">
<Grid>
<Rectangle Stroke="Black"
StrokeThickness="1"
RadiusX="4"
RadiusY="4"
Fill="{StaticResource WindowBackground}"></Rectangle>
<Grid Margin="1">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
<local:ZbWindowTitle x:Name="WindowTitle"
CanMax="{TemplateBinding CanMax}"
Title="{TemplateBinding Title}"
VerticalAlignment="Top"
MinHeight="25"
MaxHeight="25"
MinWidth="75"
Visibility="Collapsed">
</local:ZbWindowTitle>
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="WindowStyle"
Value="None">
<Setter TargetName="WindowTitle"
Property="Visibility"
Value="Visible"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--</SnippetWindow>-->
</ResourceDictionary>
窗口按回车到下一个控件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls;
<Style x:Key="Window" TargetType="{x:Type local:ZbWindow}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="WindowStyle"
Value="None"></Setter>
<Setter Property="ResizeMode"
Value="NoResize"></Setter>
<Setter Property="CanMax"
Value="Collapsed"></Setter>
<!--设置此属性才能将窗口背景设透明的效果-->
<Setter Property="AllowsTransparency"
Value="True"></Setter>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ZbWindow}">
<Grid>
<Rectangle Stroke="Black"
StrokeThickness="1"
RadiusX="4"
RadiusY="4"
Fill="{StaticResource WindowBackground}"></Rectangle>
<Grid Margin="1">
<AdornerDecorator>
<ContentPresenter />
</AdornerDecorator>
<local:ZbWindowTitle x:Name="WindowTitle"
CanMax="{TemplateBinding CanMax}"
Title="{TemplateBinding Title}"
VerticalAlignment="Top"
MinHeight="25"
MaxHeight="25"
MinWidth="75"
Visibility="Collapsed">
</local:ZbWindowTitle>
<ResizeGrip x:Name="WindowResizeGrip"
HorizontalAlignment="Right"
VerticalAlignment="Bottom"
Visibility="Collapsed"
IsTabStop="false" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="ResizeMode"
Value="CanResizeWithGrip">
<Setter TargetName="WindowResizeGrip"
Property="Visibility"
Value="Visible" />
</Trigger>
<Trigger Property="WindowStyle"
Value="None">
<Setter TargetName="WindowTitle"
Property="Visibility"
Value="Visible"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--</SnippetWindow>-->
</ResourceDictionary>
窗口按回车到下一个控件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls;
namespace Zbsoft.WpfControls
{
/// <summary>
/// 扩展函数集
/// </summary>
public static class ZbExternt
{
/// <summary>
/// 回车键到下一个控件
/// 如果控件的AcceptsReturn属性设置为真(文本接受回车键),则回车到下一个控件自动失效
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public static void EnterKeyToNext(object sender, KeyEventArgs e)
{
if (e.Source as Control != null && e.Key == Key.Enter)
{
//焦点更改方向枚举值
FocusNavigationDirection focusDirection;
//如果回车加Shift键,则到上一个控件,否则到下一个控件
if ((e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
focusDirection = FocusNavigationDirection.Previous;
else
focusDirection = FocusNavigationDirection.Next;
//焦点更改请求
TraversalRequest request = new TraversalRequest(focusDirection);
//按请求更改焦点
(e.Source as Control).MoveFocus(request);
}
}
}
}
四、测试
<my:ZbWindow x:Class="Zbsoft.OfficeClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:my="clr-namespace:Zbsoft.WpfControls;assembly=Zbsoft.WpfControls"
Title="登录"
Height="350"
Width="480"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="352"
d:DesignWidth="478"
WindowStyle="None"
ResizeMode="NoResize"
Icon="/Zbsoft.OfficeClient;component/Images/zb32.png">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="/Zbsoft.OfficeClient;component/bin/Debug/Resources/sj.jpg" />
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition MinWidth="160" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition MinHeight="180" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<Grid Grid.Row="1"
Grid.Column="1"
MinHeight="180">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Name="spTextBox"
Grid.Column="1"
VerticalAlignment="Center">
<my:ZbTextBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Yhm"
VerticalAlignment="Center"
BackPromptString="用户名" />
<my:ZbPasswordBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Mm"
VerticalAlignment="Center"
BackPromptString="密码" />
<my:ZbPasswordBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Mm1"
VerticalAlignment="Center"
BackPromptString="新密码"
Visibility="Collapsed" />
<my:ZbPasswordBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Mm2"
VerticalAlignment="Center"
BackPromptString="新密码确认"
Visibility="Collapsed" />
</StackPanel>
</Grid>
<Grid Name="spMessage"
Grid.Row="1"
VerticalAlignment="Center"
MinHeight="180"
Background="{StaticResource MessageBackground}"
Grid.Column="1"
Visibility="Collapsed">
<TextBlock Name="tbMessage"
VerticalAlignment="Center"
Padding="10"
TextWrapping="Wrap"></TextBlock>
</Grid>
<StackPanel Name="spMessageButton"
Grid.Row="2"
Grid.ColumnSpan="3"
Visibility="Collapsed"
Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<my:ZbButton HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="确定"
Width="70"
Height="30"
Click="ShowSpTextBox"></my:ZbButton>
</StackPanel>
<StackPanel Name="spButton"
Grid.Row="2"
Grid.ColumnSpan="3"
Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<my:ZbButton Content="登录"
HorizontalAlignment="Left"
Name="button1"
VerticalAlignment="Center"
Width="72"
Click="button1_Click"
Height="30"
Margin="10">
</my:ZbButton>
<my:ZbButton Content="修改密码"
Height="30"
HorizontalAlignment="Right"
Margin="10"
Name="button2"
VerticalAlignment="Center"
Click="button2_Click"
Width="73">
</my:ZbButton>
</StackPanel>
</Grid>
</my:ZbWindow>
{
/// <summary>
/// 扩展函数集
/// </summary>
public static class ZbExternt
{
/// <summary>
/// 回车键到下一个控件
/// 如果控件的AcceptsReturn属性设置为真(文本接受回车键),则回车到下一个控件自动失效
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public static void EnterKeyToNext(object sender, KeyEventArgs e)
{
if (e.Source as Control != null && e.Key == Key.Enter)
{
//焦点更改方向枚举值
FocusNavigationDirection focusDirection;
//如果回车加Shift键,则到上一个控件,否则到下一个控件
if ((e.KeyboardDevice.Modifiers & ModifierKeys.Shift) == ModifierKeys.Shift)
focusDirection = FocusNavigationDirection.Previous;
else
focusDirection = FocusNavigationDirection.Next;
//焦点更改请求
TraversalRequest request = new TraversalRequest(focusDirection);
//按请求更改焦点
(e.Source as Control).MoveFocus(request);
}
}
}
}
四、测试
<my:ZbWindow x:Class="Zbsoft.OfficeClient.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
xmlns:my="clr-namespace:Zbsoft.WpfControls;assembly=Zbsoft.WpfControls"
Title="登录"
Height="350"
Width="480"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DesignHeight="352"
d:DesignWidth="478"
WindowStyle="None"
ResizeMode="NoResize"
Icon="/Zbsoft.OfficeClient;component/Images/zb32.png">
<Grid>
<Grid.Background>
<ImageBrush ImageSource="/Zbsoft.OfficeClient;component/bin/Debug/Resources/sj.jpg" />
</Grid.Background>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition MinWidth="160" />
<ColumnDefinition Width="20" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="50"></RowDefinition>
<RowDefinition MinHeight="180" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
<Grid Grid.Row="1"
Grid.Column="1"
MinHeight="180">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="180"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Name="spTextBox"
Grid.Column="1"
VerticalAlignment="Center">
<my:ZbTextBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Yhm"
VerticalAlignment="Center"
BackPromptString="用户名" />
<my:ZbPasswordBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Mm"
VerticalAlignment="Center"
BackPromptString="密码" />
<my:ZbPasswordBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Mm1"
VerticalAlignment="Center"
BackPromptString="新密码"
Visibility="Collapsed" />
<my:ZbPasswordBox Margin="4,10"
HorizontalAlignment="Stretch"
Name="Mm2"
VerticalAlignment="Center"
BackPromptString="新密码确认"
Visibility="Collapsed" />
</StackPanel>
</Grid>
<Grid Name="spMessage"
Grid.Row="1"
VerticalAlignment="Center"
MinHeight="180"
Background="{StaticResource MessageBackground}"
Grid.Column="1"
Visibility="Collapsed">
<TextBlock Name="tbMessage"
VerticalAlignment="Center"
Padding="10"
TextWrapping="Wrap"></TextBlock>
</Grid>
<StackPanel Name="spMessageButton"
Grid.Row="2"
Grid.ColumnSpan="3"
Visibility="Collapsed"
Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<my:ZbButton HorizontalAlignment="Center"
VerticalAlignment="Center"
Content="确定"
Width="70"
Height="30"
Click="ShowSpTextBox"></my:ZbButton>
</StackPanel>
<StackPanel Name="spButton"
Grid.Row="2"
Grid.ColumnSpan="3"
Orientation="Horizontal"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<my:ZbButton Content="登录"
HorizontalAlignment="Left"
Name="button1"
VerticalAlignment="Center"
Width="72"
Click="button1_Click"
Height="30"
Margin="10">
</my:ZbButton>
<my:ZbButton Content="修改密码"
Height="30"
HorizontalAlignment="Right"
Margin="10"
Name="button2"
VerticalAlignment="Center"
Click="button2_Click"
Width="73">
</my:ZbButton>
</StackPanel>
</Grid>
</my:ZbWindow>