WPF自定义控件那些事(一)

      Wpf因其提供样式、模板等多种方式,可以为控件的外观进行定制,因此很多Wpf教材上都说Wpf自定义控件在Wpf编程中的地位已不再有WinForm编程中那么的重要。但是在一个大的项目开发中,自定义控件还是非常的重要,依然是项目的开发、维护的基础。本人通过编写一些WPF自定义控件,来学习WPF编程,感受WPF开发的快乐与其魅力,特写系列文章--WPF自定义控件那些事,希望能对WPF的初学者一些帮助。
     

自定义窗口

 

      自定义窗口,实现窗口圆角,当然在此基础上也可以是非规则的窗口,自定义的窗口标题栏,回车键转换焦点,按住鼠标左键,移动窗口位置等。以下是效果图

WPF自定义控件那些事(一)_第1张图片

一、 在自定义控件之前,先将一些要用到的画刷、颜色等可以共享的资源保存到一个公共资源字典中。
ZbShared.xaml
http://schemas.microsoft.com/winfx/2006/xaml/presentation
"
                    xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:s="clr-namespace:System;assembly=mscorlib">


1

2

4,3,4,3

4



          Color="BlueViolet">
#FF0000FF

          Color="Green">
#FFFF0000

#FFFFFFFF

          Color="Gray">

          Color="#FFC5CBF9">
#FFC5CBF9

          Color="#FFE8EDF9">
#FFE8EDF9



          Color="White">

          Color="Black">

       StartPoint="0,0">
        Offset="0" />
        Offset="1" />



       StartPoint="0.5,0">
         Offset="0" />
         Offset="1" />

#FFCCCCCC
#FF888888
#FF444444

#FF888888
#FF444444
#FFAAAAAA
#FF888888
#FF0000FF
#FF0000FF
Black

#FFE8EDF9
       EndPoint="0.5,1"
       StartPoint="0.5,0">
         Color="{StaticResource WindowColor}"/>
         Color="#AAFFFFFF"/>
#FFC5CBF9
#FF7381F9
#FFE8EDF9
#FFC5CBF9
#FF888888
#FFC5CBF9
#FFDDDDDD
White
#FF7381F9
#FF211AA9
#FF3843C4
#FF211AA9
#FF444444
sc#1, 0.004391443, 0.002428215, 0.242281124

2
4
4
red

       StartPoint="0.5,0">
 
 

#FF0B1AFD

       StartPoint="0.5,0">
 
 

#FF071CCA

#00FFFFFF


             Storyboard.TargetName="Border">
            Value="{StaticResource WindowButtonBorderBackgroundFocuse}" />
 

             Storyboard.TargetName="Border">
            Value="{StaticResource WindowButtonBorderFocuse}" />
 


             Storyboard.TargetName="Border">
            Value="0,0">
   
    
   

  

            Value="0.5,0">
   
    
   

  

 

             Storyboard.TargetName="Border">
            Value="0.5,1">
   
    
   

  

            Value="0.5,1">
   
    
   

  

 

             Storyboard.TargetName="Border">
            Value="#FFF9F473">
   
    
   

  

            Value="#FF7381F9">
   
    
   

  

 

       StartPoint="0.5,0">
         Color="#AAFFFFFF" />
         Color="#44FFFFFF" />


二、 自定义窗口标题栏控件
ZbWindowTitle.xaml
             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">

 
  
   
  

 



 
  
  
  
  
  
  
  
 

 
         Text="{Binding Path=Title,RelativeSource={RelativeSource AncestorType={x:Type 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
{
    ///
    /// WindowTitle.xaml 的交互逻辑
    ///

    public partial class ZbWindowTitle : UserControl
    {
        public static DependencyProperty CanMaxProperty = DependencyProperty.Register("CanMax",
            typeof(Visibility), typeof(ZbWindowTitle));
        ///
        /// 是否可以最大化
        ///

        public Visibility CanMax
        {
            get { return (Visibility)GetValue(CanMaxProperty); }
            set { SetValue(CanMaxProperty, value); }
        }
        public static DependencyProperty TitleProperty = DependencyProperty.Register("Title",
            typeof(string), typeof(ZbWindowTitle));
        ///
        /// 窗口标题
        ///

        public string Title
        {
            get { return (string)GetValue(TitleProperty); }
            set { SetValue(TitleProperty, value); }
        }
        public static DependencyProperty IconProperty = DependencyProperty.Register("Icon",
            typeof(ImageSource), typeof(ZbWindowTitle));
        ///
        /// 窗口标题图标
        ///

        public ImageSource Icon
        {
            get { return (ImageSource)GetValue(IconProperty); }
            set { SetValue(IconProperty, value); }
        }
        public ZbWindowTitle()
        {
            InitializeComponent();
        }
        ///
        /// 关闭按钮
        ///

        ///
        ///
        private void CloseButton_Click(object sender, RoutedEventArgs e)
        {
            Window w = Window.GetWindow(this);
            if (w != null)
                w.Close();
        }
        ///
        /// 最小化按钮
        ///

        ///
        ///
        private void minButton_Click(object sender, RoutedEventArgs e)
        {
            Window w = Window.GetWindow(this);
            if (w != null)
                w.WindowState = WindowState.Minimized;
        }
        ///
        /// 最大化按钮
        ///

        ///
        ///
        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

http://schemas.microsoft.com/winfx/2006/xaml/presentation
"
     xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="clr-namespace:Zbsoft.WpfControls">

 





三、自定义窗口
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
namespace Zbsoft.WpfControls
{
    ///
    /// 窗口类
    ///

    public class ZbWindow : Window
    {
        ///
        /// 窗口能否最大化
        ///

        public static DependencyProperty CanMaxProperty = DependencyProperty.Register("CanMax",
            typeof(Visibility), typeof(ZbWindow));
        ///
        /// 窗口能否最大化
        ///

        public Visibility CanMax
        {
            get { return (Visibility)GetValue(CanMaxProperty); }
            set { SetValue(CanMaxProperty, value); }
        }
        ///
        /// 初始化时,设置样式,并添加事件处理响应回车键到下一个控件
        ///

        ///
        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);
        }
        ///
        /// 移动窗口位置
        ///

        ///
        ///
        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
http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="
http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:local="clr-namespace:Zbsoft.WpfControls">

 
 





窗口按回车到下一个控件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Input;
using System.Windows.Controls;
namespace Zbsoft.WpfControls
{
    ///
    /// 扩展函数集
    ///

    public static class ZbExternt
    {
        ///
        /// 回车键到下一个控件
        /// 如果控件的AcceptsReturn属性设置为真(文本接受回车键),则回车到下一个控件自动失效
        ///

        ///
        ///
        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);
            }
          }
    }
}

四、测试
        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.Column="1"
      MinHeight="180">
  
   
   
  

         Grid.Column="1"
      VerticalAlignment="Center">
             HorizontalAlignment="Stretch"
         Name="Yhm"
         VerticalAlignment="Center"
         BackPromptString="用户名" />
              HorizontalAlignment="Stretch"
          Name="Mm"
          VerticalAlignment="Center"
          BackPromptString="密码" />
              HorizontalAlignment="Stretch"
          Name="Mm1"
          VerticalAlignment="Center"
          BackPromptString="新密码"
          Visibility="Collapsed" />
              HorizontalAlignment="Stretch"
          Name="Mm2"
          VerticalAlignment="Center"
          BackPromptString="新密码确认"
          Visibility="Collapsed" />
  

 

       Grid.Row="1"
     VerticalAlignment="Center"
     MinHeight="180"
     Background="{StaticResource MessageBackground}"
     Grid.Column="1"
     Visibility="Collapsed">
           VerticalAlignment="Center"
        Padding="10"
        TextWrapping="Wrap">

 

       Grid.Row="2"
     Grid.ColumnSpan="3"
     Visibility="Collapsed"
     Orientation="Horizontal"
     VerticalAlignment="Center"
     HorizontalAlignment="Center">
          VerticalAlignment="Center"
       Content="确定"
       Width="70"
       Height="30"
       Click="ShowSpTextBox">

 

       Grid.Row="2"
     Grid.ColumnSpan="3"
     Orientation="Horizontal"
     VerticalAlignment="Center"
     HorizontalAlignment="Center">
          HorizontalAlignment="Left"
       Name="button1"
       VerticalAlignment="Center"
       Width="72"
       Click="button1_Click"
       Height="30"
       Margin="10">
  

          Height="30"
       HorizontalAlignment="Right"
       Margin="10"
       Name="button2"
       VerticalAlignment="Center"
       Click="button2_Click"
       Width="73">
  

 



你可能感兴趣的:(.net)