zoukankan      html  css  js  c++  java
  • WPF自定义控件与样式(15)-终结篇 & 系列文章索引 & 源码共享

    系列文章目录   

    WPF自定义控件与样式(1)-矢量字体图标(iconfont)

    WPF自定义控件与样式(2)-自定义按钮FButton

    WPF自定义控件与样式(3)-TextBox & RichTextBox & PasswordBox样式、水印、Label标签、功能扩展

    WPF自定义控件与样式(4)-CheckBox/RadioButton自定义样式

    WPF自定义控件与样式(5)-Calendar/DatePicker日期控件自定义样式及扩展

    WPF自定义控件与样式(6)-ScrollViewer与ListBox自定义样式

    WPF自定义控件与样式(7)-列表控件DataGrid与ListView自定义样式

    WPF自定义控件与样式(8)-ComboBox与自定义多选控件MultComboBox

    WPF自定义控件与样式(9)-树控件TreeView与菜单Menu-ContextMenu

    WPF自定义控件与样式(10)-进度控件ProcessBar自定义样 

    WPF自定义控件与样式(11)-等待/忙/正在加载状态-控件实现

    WPF自定义控件与样式(12)-缩略图ThumbnailImage /gif动画图/图片列表

    WPF自定义控件与样式(13)-自定义窗体Window & 自适应内容大小消息框MessageBox

    WPF自定义控件与样式(14)-轻量MVVM模式实践 

    WPF自定义控件与样式(15)-终结篇

    源代码下载地址http://files.cnblogs.com/files/anding/Util.Controls.zip

    Github项目地址https://github.com/kwonganding/wpf.controls

    一.总结.声明

      关于本WPF,本人也只能算是一个刚入门的,在学习中和工作中,学习、借鉴了很多网友的文章和开源的项目的知识。发现提供实际项目开发需要的基础控件、样式的文章大都比较散,不成系列。因此基于现在项目中使用的基础UI库,写了这个系列,希望对有需要的人有所帮助。

      本系列包括本文共15篇,就到此为止了。关于一些问题再次说明一下:

    • 每一篇文章中都给出了基本所有主要代码,目的仅供参考学习,由于目前还是公司在使用中的项目,因此不便提供完整项目源码,有需要的同学还是多动动手吧!
    • 对于确实需要源码参考学的,推荐开源项目MahApps.Metro(http://mahapps.com/),我在那里面学习借鉴了很多,本系列中不少样式中都有她(就是她)的影子。
    • 本文会把一些额外遗漏的资源或代码一并提供出来

    二.附录.本系列补充资源

    2.1附加属性

      很多样式中使用了附加属性来对基础控件扩展,ControlAttachProperty.cs所有代码:  

        /// <summary>
        /// 公共附加属性
        /// </summary>
        public static class ControlAttachProperty
        {
            /************************************ Attach Property **************************************/
    
            #region FocusBackground 获得焦点背景色,
    
            public static readonly DependencyProperty FocusBackgroundProperty = DependencyProperty.RegisterAttached(
                "FocusBackground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static void SetFocusBackground(DependencyObject element, Brush value)
            {
                element.SetValue(FocusBackgroundProperty, value);
            }
    
            public static Brush GetFocusBackground(DependencyObject element)
            {
                return (Brush)element.GetValue(FocusBackgroundProperty);
            }
    
            #endregion
    
            #region FocusForeground 获得焦点前景色,
    
            public static readonly DependencyProperty FocusForegroundProperty = DependencyProperty.RegisterAttached(
                "FocusForeground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static void SetFocusForeground(DependencyObject element, Brush value)
            {
                element.SetValue(FocusForegroundProperty, value);
            }
    
            public static Brush GetFocusForeground(DependencyObject element)
            {
                return (Brush)element.GetValue(FocusForegroundProperty);
            }
    
            #endregion
    
            #region MouseOverBackgroundProperty 鼠标悬浮背景色
    
            public static readonly DependencyProperty MouseOverBackgroundProperty = DependencyProperty.RegisterAttached(
                "MouseOverBackground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static void SetMouseOverBackground(DependencyObject element, Brush value)
            {
                element.SetValue(MouseOverBackgroundProperty, value);
            }
    
            public static Brush MouseOverBackground(DependencyObject element)
            {
                return (Brush)element.GetValue(FocusBackgroundProperty);
            }
    
            #endregion
    
            #region MouseOverForegroundProperty 鼠标悬浮前景色
    
            public static readonly DependencyProperty MouseOverForegroundProperty = DependencyProperty.RegisterAttached(
                "MouseOverForeground", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static void SetMouseOverForeground(DependencyObject element, Brush value)
            {
                element.SetValue(MouseOverForegroundProperty, value);
            }
    
            public static Brush MouseOverForeground(DependencyObject element)
            {
                return (Brush)element.GetValue(FocusForegroundProperty);
            }
    
            #endregion
    
            #region FocusBorderBrush 焦点边框色,输入控件
    
            public static readonly DependencyProperty FocusBorderBrushProperty = DependencyProperty.RegisterAttached(
                "FocusBorderBrush", typeof(Brush), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
            public static void SetFocusBorderBrush(DependencyObject element, Brush value)
            {
                element.SetValue(FocusBorderBrushProperty, value);
            }
            public static Brush GetFocusBorderBrush(DependencyObject element)
            {
                return (Brush)element.GetValue(FocusBorderBrushProperty);
            }
    
            #endregion
    
            #region MouseOverBorderBrush 鼠标进入边框色,输入控件
    
            public static readonly DependencyProperty MouseOverBorderBrushProperty =
                DependencyProperty.RegisterAttached("MouseOverBorderBrush", typeof(Brush), typeof(ControlAttachProperty),
                    new FrameworkPropertyMetadata(Brushes.Transparent,
                        FrameworkPropertyMetadataOptions.AffectsRender | FrameworkPropertyMetadataOptions.Inherits));
    
            /// <summary>
            /// Sets the brush used to draw the mouse over brush.
            /// </summary>
            public static void SetMouseOverBorderBrush(DependencyObject obj, Brush value)
            {
                obj.SetValue(MouseOverBorderBrushProperty, value);
            }
    
            /// <summary>
            /// Gets the brush used to draw the mouse over brush.
            /// </summary>
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            [AttachedPropertyBrowsableForType(typeof(CheckBox))]
            [AttachedPropertyBrowsableForType(typeof(RadioButton))]
            [AttachedPropertyBrowsableForType(typeof(DatePicker))]
            [AttachedPropertyBrowsableForType(typeof(ComboBox))]
            [AttachedPropertyBrowsableForType(typeof(RichTextBox))]
            public static Brush GetMouseOverBorderBrush(DependencyObject obj)
            {
                return (Brush)obj.GetValue(MouseOverBorderBrushProperty);
            }
    
            #endregion
    
            #region AttachContentProperty 附加组件模板
            /// <summary>
            /// 附加组件模板
            /// </summary>
            public static readonly DependencyProperty AttachContentProperty = DependencyProperty.RegisterAttached(
                "AttachContent", typeof(ControlTemplate), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static ControlTemplate GetAttachContent(DependencyObject d)
            {
                return (ControlTemplate)d.GetValue(AttachContentProperty);
            }
    
            public static void SetAttachContent(DependencyObject obj, ControlTemplate value)
            {
                obj.SetValue(AttachContentProperty, value);
            }
            #endregion
    
            #region WatermarkProperty 水印
            /// <summary>
            /// 水印
            /// </summary>
            public static readonly DependencyProperty WatermarkProperty = DependencyProperty.RegisterAttached(
                "Watermark", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));
    
            public static string GetWatermark(DependencyObject d)
            {
                return (string)d.GetValue(WatermarkProperty);
            }
    
            public static void SetWatermark(DependencyObject obj, string value)
            {
                obj.SetValue(WatermarkProperty, value);
            }
            #endregion
    
            #region FIconProperty 字体图标
            /// <summary>
            /// 字体图标
            /// </summary>
            public static readonly DependencyProperty FIconProperty = DependencyProperty.RegisterAttached(
                "FIcon", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(""));
    
            public static string GetFIcon(DependencyObject d)
            {
                return (string)d.GetValue(FIconProperty);
            }
    
            public static void SetFIcon(DependencyObject obj, string value)
            {
                obj.SetValue(FIconProperty, value);
            }
            #endregion
    
            #region FIconSizeProperty 字体图标大小
            /// <summary>
            /// 字体图标
            /// </summary>
            public static readonly DependencyProperty FIconSizeProperty = DependencyProperty.RegisterAttached(
                "FIconSize", typeof(double), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(12D));
    
            public static double GetFIconSize(DependencyObject d)
            {
                return (double)d.GetValue(FIconSizeProperty);
            }
    
            public static void SetFIconSize(DependencyObject obj, double value)
            {
                obj.SetValue(FIconSizeProperty, value);
            }
            #endregion
    
            #region FIconMarginProperty 字体图标边距
            /// <summary>
            /// 字体图标
            /// </summary>
            public static readonly DependencyProperty FIconMarginProperty = DependencyProperty.RegisterAttached(
                "FIconMargin", typeof(Thickness), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static Thickness GetFIconMargin(DependencyObject d)
            {
                return (Thickness)d.GetValue(FIconMarginProperty);
            }
    
            public static void SetFIconMargin(DependencyObject obj, Thickness value)
            {
                obj.SetValue(FIconMarginProperty, value);
            }
            #endregion
    
            #region AllowsAnimationProperty 启用旋转动画
            /// <summary>
            /// 启用旋转动画
            /// </summary>
            public static readonly DependencyProperty AllowsAnimationProperty = DependencyProperty.RegisterAttached("AllowsAnimation"
                , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, AllowsAnimationChanged));
    
            public static bool GetAllowsAnimation(DependencyObject d)
            {
                return (bool)d.GetValue(AllowsAnimationProperty);
            }
    
            public static void SetAllowsAnimation(DependencyObject obj, bool value)
            {
                obj.SetValue(AllowsAnimationProperty, value);
            }
    
            /// <summary>
            /// 旋转动画刻度
            /// </summary>
            private static DoubleAnimation RotateAnimation = new DoubleAnimation(0, new Duration(TimeSpan.FromMilliseconds(200)));
    
            /// <summary>
            /// 绑定动画事件
            /// </summary>
            private static void AllowsAnimationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var uc = d as FrameworkElement;
                if (uc == null) return;
                if (uc.RenderTransformOrigin == new Point(0, 0))
                {
                    uc.RenderTransformOrigin = new Point(0.5, 0.5);
                    RotateTransform trans = new RotateTransform(0);
                    uc.RenderTransform = trans;
                }
                var value = (bool)e.NewValue;
                if (value)
                {
                    RotateAnimation.To = 180;
                    uc.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, RotateAnimation);
                }
                else
                {
                    RotateAnimation.To = 0;
                    uc.RenderTransform.BeginAnimation(RotateTransform.AngleProperty, RotateAnimation);
                }
            }
            #endregion
    
            #region CornerRadiusProperty Border圆角
            /// <summary>
            /// Border圆角
            /// </summary>
            public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.RegisterAttached(
                "CornerRadius", typeof(CornerRadius), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            public static CornerRadius GetCornerRadius(DependencyObject d)
            {
                return (CornerRadius)d.GetValue(CornerRadiusProperty);
            }
    
            public static void SetCornerRadius(DependencyObject obj, CornerRadius value)
            {
                obj.SetValue(CornerRadiusProperty, value);
            }
            #endregion
    
            #region LabelProperty TextBox的头部Label
            /// <summary>
            /// TextBox的头部Label
            /// </summary>
            public static readonly DependencyProperty LabelProperty = DependencyProperty.RegisterAttached(
                "Label", typeof(string), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static string GetLabel(DependencyObject d)
            {
                return (string)d.GetValue(LabelProperty);
            }
    
            public static void SetLabel(DependencyObject obj, string value)
            {
                obj.SetValue(LabelProperty, value);
            }
            #endregion
    
            #region LabelTemplateProperty TextBox的头部Label模板
            /// <summary>
            /// TextBox的头部Label模板
            /// </summary>
            public static readonly DependencyProperty LabelTemplateProperty = DependencyProperty.RegisterAttached(
                "LabelTemplate", typeof(ControlTemplate), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(null));
    
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static ControlTemplate GetLabelTemplate(DependencyObject d)
            {
                return (ControlTemplate)d.GetValue(LabelTemplateProperty);
            }
    
            public static void SetLabelTemplate(DependencyObject obj, ControlTemplate value)
            {
                obj.SetValue(LabelTemplateProperty, value);
            }
            #endregion
    
            /************************************ RoutedUICommand Behavior enable **************************************/
    
            #region IsClearTextButtonBehaviorEnabledProperty 清除输入框Text值按钮行为开关(设为ture时才会绑定事件)
            /// <summary>
            /// 清除输入框Text值按钮行为开关
            /// </summary>
            public static readonly DependencyProperty IsClearTextButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsClearTextButtonBehaviorEnabled"
                , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsClearTextButtonBehaviorEnabledChanged));
    
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static bool GetIsClearTextButtonBehaviorEnabled(DependencyObject d)
            {
                return (bool)d.GetValue(IsClearTextButtonBehaviorEnabledProperty);
            }
    
            public static void SetIsClearTextButtonBehaviorEnabled(DependencyObject obj, bool value)
            {
                obj.SetValue(IsClearTextButtonBehaviorEnabledProperty, value);
            }
    
            /// <summary>
            /// 绑定清除Text操作的按钮事件
            /// </summary>
            private static void IsClearTextButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var button = d as FButton;
                if (e.OldValue != e.NewValue && button != null)
                {
                    button.CommandBindings.Add(ClearTextCommandBinding);
                }
            }
    
            #endregion
    
            #region IsOpenFileButtonBehaviorEnabledProperty 选择文件命令行为开关
            /// <summary>
            /// 选择文件命令行为开关
            /// </summary>
            public static readonly DependencyProperty IsOpenFileButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsOpenFileButtonBehaviorEnabled"
                , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsOpenFileButtonBehaviorEnabledChanged));
    
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static bool GetIsOpenFileButtonBehaviorEnabled(DependencyObject d)
            {
                return (bool)d.GetValue(IsOpenFileButtonBehaviorEnabledProperty);
            }
    
            public static void SetIsOpenFileButtonBehaviorEnabled(DependencyObject obj, bool value)
            {
                obj.SetValue(IsOpenFileButtonBehaviorEnabledProperty, value);
            }
    
            private static void IsOpenFileButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var button = d as FButton;
                if (e.OldValue != e.NewValue && button != null)
                {
                    button.CommandBindings.Add(OpenFileCommandBinding);
                }
            }
    
            #endregion
    
            #region IsOpenFolderButtonBehaviorEnabledProperty 选择文件夹命令行为开关
            /// <summary>
            /// 选择文件夹命令行为开关
            /// </summary>
            public static readonly DependencyProperty IsOpenFolderButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsOpenFolderButtonBehaviorEnabled"
                , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsOpenFolderButtonBehaviorEnabledChanged));
    
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static bool GetIsOpenFolderButtonBehaviorEnabled(DependencyObject d)
            {
                return (bool)d.GetValue(IsOpenFolderButtonBehaviorEnabledProperty);
            }
    
            public static void SetIsOpenFolderButtonBehaviorEnabled(DependencyObject obj, bool value)
            {
                obj.SetValue(IsOpenFolderButtonBehaviorEnabledProperty, value);
            }
    
            private static void IsOpenFolderButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var button = d as FButton;
                if (e.OldValue != e.NewValue && button != null)
                {
                    button.CommandBindings.Add(OpenFolderCommandBinding);
                }
            }
    
            #endregion
    
            #region IsSaveFileButtonBehaviorEnabledProperty 选择文件保存路径及名称
            /// <summary>
            /// 选择文件保存路径及名称
            /// </summary>
            public static readonly DependencyProperty IsSaveFileButtonBehaviorEnabledProperty = DependencyProperty.RegisterAttached("IsSaveFileButtonBehaviorEnabled"
                , typeof(bool), typeof(ControlAttachProperty), new FrameworkPropertyMetadata(false, IsSaveFileButtonBehaviorEnabledChanged));
    
            [AttachedPropertyBrowsableForType(typeof(TextBox))]
            public static bool GetIsSaveFileButtonBehaviorEnabled(DependencyObject d)
            {
                return (bool)d.GetValue(IsSaveFileButtonBehaviorEnabledProperty);
            }
    
            public static void SetIsSaveFileButtonBehaviorEnabled(DependencyObject obj, bool value)
            {
                obj.SetValue(IsSaveFileButtonBehaviorEnabledProperty, value);
            }
    
            private static void IsSaveFileButtonBehaviorEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
            {
                var button = d as FButton;
                if (e.OldValue != e.NewValue && button != null)
                {
                    button.CommandBindings.Add(SaveFileCommandBinding);
                }
            }
    
            #endregion
    
            /************************************ RoutedUICommand **************************************/
    
            #region ClearTextCommand 清除输入框Text事件命令
    
            /// <summary>
            /// 清除输入框Text事件命令,需要使用IsClearTextButtonBehaviorEnabledChanged绑定命令
            /// </summary>
            public static RoutedUICommand ClearTextCommand { get; private set; }
    
            /// <summary>
            /// ClearTextCommand绑定事件
            /// </summary>
            private static readonly CommandBinding ClearTextCommandBinding;
    
            /// <summary>
            /// 清除输入框文本值
            /// </summary>
            private static void ClearButtonClick(object sender, ExecutedRoutedEventArgs e)
            {
                var tbox = e.Parameter as FrameworkElement;
                if (tbox == null) return;
                if (tbox is TextBox)
                {
                    ((TextBox)tbox).Clear();
                }
                if (tbox is PasswordBox)
                {
                    ((PasswordBox)tbox).Clear();
                }
                if (tbox is ComboBox)
                {
                    var cb = tbox as ComboBox;
                    cb.SelectedItem = null;
                    cb.Text = string.Empty;
                }
                if (tbox is MultiComboBox)
                {
                    var cb = tbox as MultiComboBox;
                    cb.SelectedItem = null;
                    cb.UnselectAll();
                    cb.Text = string.Empty;
                }
                if (tbox is DatePicker)
                {
                    var dp = tbox as DatePicker;
                    dp.SelectedDate = null;
                    dp.Text = string.Empty;
                }
                tbox.Focus();
            }
    
            #endregion
    
            #region OpenFileCommand 选择文件命令
    
            /// <summary>
            /// 选择文件命令,需要使用IsClearTextButtonBehaviorEnabledChanged绑定命令
            /// </summary>
            public static RoutedUICommand OpenFileCommand { get; private set; }
    
            /// <summary>
            /// OpenFileCommand绑定事件
            /// </summary>
            private static readonly CommandBinding OpenFileCommandBinding;
    
            /// <summary>
            /// 执行OpenFileCommand
            /// </summary>
            private static void OpenFileButtonClick(object sender, ExecutedRoutedEventArgs e)
            {
                var tbox = e.Parameter as FrameworkElement;
                var txt = tbox as TextBox;
                string filter = txt.Tag == null ? "所有文件(*.*)|*.*" : txt.Tag.ToString();
                if (filter.Contains(".bin"))
                {
                    filter += "|所有文件(*.*)|*.*";
                }
                if (txt == null) return;
                OpenFileDialog fd = new OpenFileDialog();
                fd.Title = "请选择文件";
                //“图像文件(*.bmp, *.jpg)|*.bmp;*.jpg|所有文件(*.*)|*.*”
                fd.Filter = filter;
                fd.FileName = txt.Text.Trim();
                if (fd.ShowDialog() == true)
                {
                    txt.Text = fd.FileName;
                }
                tbox.Focus();
            }
    
            #endregion
    
            #region OpenFolderCommand 选择文件夹命令
    
            /// <summary>
            /// 选择文件夹命令
            /// </summary>
            public static RoutedUICommand OpenFolderCommand { get; private set; }
    
            /// <summary>
            /// OpenFolderCommand绑定事件
            /// </summary>
            private static readonly CommandBinding OpenFolderCommandBinding;
    
            /// <summary>
            /// 执行OpenFolderCommand
            /// </summary>
            private static void OpenFolderButtonClick(object sender, ExecutedRoutedEventArgs e)
            {
                var tbox = e.Parameter as FrameworkElement;
                var txt = tbox as TextBox;
                if (txt == null) return;
                FolderBrowserDialog fd = new FolderBrowserDialog();
                fd.Description = "请选择文件路径";
                fd.SelectedPath = txt.Text.Trim();
                if (fd.ShowDialog() == DialogResult.OK)
                {
                    txt.Text = fd.SelectedPath;
                }
                tbox.Focus();
            }
    
            #endregion
    
            #region SaveFileCommand 选择文件保存路径及名称
    
            /// <summary>
            /// 选择文件保存路径及名称
            /// </summary>
            public static RoutedUICommand SaveFileCommand { get; private set; }
    
            /// <summary>
            /// SaveFileCommand绑定事件
            /// </summary>
            private static readonly CommandBinding SaveFileCommandBinding;
    
            /// <summary>
            /// 执行OpenFileCommand
            /// </summary>
            private static void SaveFileButtonClick(object sender, ExecutedRoutedEventArgs e)
            {
                var tbox = e.Parameter as FrameworkElement;
                var txt = tbox as TextBox;
                if (txt == null) return;
                SaveFileDialog fd = new SaveFileDialog();
                fd.Title = "文件保存路径";
                fd.Filter = "所有文件(*.*)|*.*";
                fd.FileName = txt.Text.Trim();
                if (fd.ShowDialog() == DialogResult.OK)
                {
                    txt.Text = fd.FileName;
                }
                tbox.Focus();
            }
    
            #endregion
    
    
            /// <summary>
            /// 静态构造函数
            /// </summary>
            static ControlAttachProperty()
            {
                //ClearTextCommand
                ClearTextCommand = new RoutedUICommand();
                ClearTextCommandBinding = new CommandBinding(ClearTextCommand);
                ClearTextCommandBinding.Executed += ClearButtonClick;
                //OpenFileCommand
                OpenFileCommand = new RoutedUICommand();
                OpenFileCommandBinding = new CommandBinding(OpenFileCommand);
                OpenFileCommandBinding.Executed += OpenFileButtonClick;
                //OpenFolderCommand
                OpenFolderCommand = new RoutedUICommand();
                OpenFolderCommandBinding = new CommandBinding(OpenFolderCommand);
                OpenFolderCommandBinding.Executed += OpenFolderButtonClick;
    
                SaveFileCommand = new RoutedUICommand();
                SaveFileCommandBinding = new CommandBinding(SaveFileCommand);
                SaveFileCommandBinding.Executed += SaveFileButtonClick;
            }
        }
    View Code

      其中有一个比较好玩的附加属性就是AllowsAnimationProperty,实现旋转动画的支持,类型为bool,可以有很多种使用方式,如绑定到普通控件的IsMouseOver上,当鼠标悬浮就旋转180度,移开又转回去,效果(gif录制的问题,看上去没有那么流程):

     

      也可以绑定到CheckBox、RadioButton、ToggleButton的IsChecked属性上。

                <TextBlock Text="&#xe602;" Style="{StaticResource FIcon}" Margin="3" FontSize="40" 
                           core:ControlAttachProperty.AllowsAnimation="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}"></TextBlock>
                <core:FImage Margin="3" Width="30" Height="30" Source="Images/qq.png" 
    core:ControlAttachProperty.AllowsAnimation
    ="{Binding IsMouseOver,RelativeSource={RelativeSource Self}}"></core:FImage>

    2.2扩展方法

      静态扩展类ControlExtession.cs代码:  

        public static class ControlExtession
        {
            #region BindCommand
    
            /// <summary>
            /// 绑定命令和命令事件到宿主UI
            /// </summary>
            public static void BindCommand(this UIElement @ui, ICommand com, Action<object, ExecutedRoutedEventArgs> call)
            {
                var bind = new CommandBinding(com);
                bind.Executed += new ExecutedRoutedEventHandler(call);
                @ui.CommandBindings.Add(bind);
            }
    
            /// <summary>
            /// 绑定RelayCommand命令到宿主UI
            /// </summary>
            public static void BindCommand(this UIElement @ui, RelayCommand<object> com)
            {
                var bind = new CommandBinding(com);
                bind.Executed += delegate(object sender, ExecutedRoutedEventArgs e)
                {
                    com.ExecuteCommand(e.Parameter);
                };
                @ui.CommandBindings.Add(bind);
            }
    
            #endregion
    
            #region TreeView操作扩展方法
            //code:http://www.codeproject.com/Articles/36193/WPF-TreeView-tools
    
            /// <summary>
            /// Returns the TreeViewItem of a data bound object.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            /// <returns>The TreeViewItem of the data bound object or null.</returns>
            public static TreeViewItem GetItemFromObject(this TreeView treeView, object obj)
            {
                try
                {
                    DependencyObject dObject = GetContainerFormObject(treeView, obj);
                    TreeViewItem tvi = dObject as TreeViewItem;
                    while (tvi == null)
                    {
                        dObject = VisualTreeHelper.GetParent(dObject);
                        tvi = dObject as TreeViewItem;
                    }
                    return tvi;
                }
                catch
                {
                }
                return null;
            }
    
            private static DependencyObject GetContainerFormObject(ItemsControl item, object obj)
            {
                if (item == null)
                    return null;
    
                DependencyObject dObject = null;
                dObject = item.ItemContainerGenerator.ContainerFromItem(obj);
    
                if (dObject != null)
                    return dObject;
    
                var query = from childItem in item.Items.Cast<object>()
                            let childControl = item.ItemContainerGenerator.ContainerFromItem(childItem) as ItemsControl
                            select GetContainerFormObject(childControl, obj);
    
                return query.FirstOrDefault(i => i != null);
            }
    
            /// <summary>
            /// Selects a data bound object of a TreeView.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            public static void SelectObject(this TreeView treeView, object obj)
            {
                treeView.SelectObject(obj, true);
            }
    
            /// <summary>
            /// Selects or deselects a data bound object of a TreeView.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            /// <param name="selected">select or deselect</param>
            public static void SelectObject(this TreeView treeView, object obj, bool selected)
            {
                var tvi = treeView.GetItemFromObject(obj);
                if (tvi != null)
                {
                    tvi.IsSelected = selected;
                }
            }
    
            /// <summary>
            /// Returns if a data bound object of a TreeView is selected.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            /// <returns>Returns true if the object is selected, and false if it is not selected or obj is not in the tree.</returns>
            public static bool IsObjectSelected(this TreeView treeView, object obj)
            {
                var tvi = treeView.GetItemFromObject(obj);
                if (tvi != null)
                {
                    return tvi.IsSelected;
                }
                return false;
            }
    
            /// <summary>
            /// Returns if a data bound object of a TreeView is focused.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            /// <returns>Returns true if the object is focused, and false if it is not focused or obj is not in the tree.</returns>
            public static bool IsObjectFocused(this TreeView treeView, object obj)
            {
                var tvi = treeView.GetItemFromObject(obj);
                if (tvi != null)
                {
                    return tvi.IsFocused;
                }
                return false;
            }
    
            /// <summary>
            /// Expands a data bound object of a TreeView.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            public static void ExpandObject(this TreeView treeView, object obj)
            {
                treeView.ExpandObject(obj, true);
            }
    
            /// <summary>
            /// Expands or collapses a data bound object of a TreeView.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            /// <param name="expanded">expand or collapse</param>
            public static void ExpandObject(this TreeView treeView, object obj, bool expanded)
            {
                var tvi = treeView.GetItemFromObject(obj);
                if (tvi != null)
                {
                    tvi.IsExpanded = expanded;
                    if (expanded)
                    {
                        // update layout, so that following calls to f.e. SelectObject on child nodes will 
                        // find theire TreeViewNodes
                        treeView.UpdateLayout();
                    }
                }
            }
    
            /// <summary>
            /// Returns if a douta bound object of a TreeView is expanded.
            /// </summary>
            /// <param name="treeView">TreeView</param>
            /// <param name="obj">Data bound object</param>
            /// <returns>Returns true if the object is expanded, and false if it is collapsed or obj is not in the tree.</returns>
            public static bool IsObjectExpanded(this TreeView treeView, object obj)
            {
                var tvi = treeView.GetItemFromObject(obj);
                if (tvi != null)
                {
                    return tvi.IsExpanded;
                }
                return false;
            }
    
            /// <summary>
            /// Retuns the parent TreeViewItem.
            /// </summary>
            /// <param name="item">TreeViewItem</param>
            /// <returns>Parent TreeViewItem</returns>
            public static TreeViewItem GetParentItem(this TreeViewItem item)
            {
                var dObject = VisualTreeHelper.GetParent(item);
                TreeViewItem tvi = dObject as TreeViewItem;
                while (tvi == null)
                {
                    dObject = VisualTreeHelper.GetParent(dObject);
                    tvi = dObject as TreeViewItem;
                }
                return tvi;
            }
    
            #endregion
    
        }
    View Code

    2.3配色资源Colors.xaml

      本系列前面文章中,基本所有样式中都没有直接使用具体色彩,而是通过资源的方式配置的,这些配色资源都在Colors.xaml中。这样的设计理论上可以实现换肤,在不同客户端中也很容易定制自己需要的风格色彩搭配。 Colors.xaml代码: 

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:sys="clr-namespace:System;assembly=mscorlib"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    
        <!--Window窗体-->
        <SolidColorBrush x:Key="WindowBackground" Color="#093B5D"></SolidColorBrush>
        <SolidColorBrush x:Key="WindowInnerBackground" Color="Transparent"></SolidColorBrush>
        <!--<ImageBrush x:Key="WindowInnerBackground" Stretch="Fill"  
                    ImageSource="pack://application:,,,/XLY.Framework.WPFTest;component/Images/back/b2.jpg"  Opacity="1"
                    Viewport="0,0,1,1" ViewportUnits="Absolute" TileMode="Tile" AlignmentX="Left" AlignmentY="Top"/>-->
        
        <SolidColorBrush x:Key="WindowBorderBrush" Color="#920892"></SolidColorBrush>
        <DropShadowEffect x:Key="WindowDropShadow" Color="#F472F4" BlurRadius="8" ShadowDepth="0" Direction="0" Opacity="0.7" />
        <SolidColorBrush x:Key="CaptionForeground" Color="White"></SolidColorBrush>
        <!--<LinearGradientBrush x:Key="CaptionBackground" StartPoint="0.5,0" EndPoint="0.5,1">
            <GradientStop Color="#571457" Offset="0"/>
            <GradientStop Color="#6A196A" Offset="1"/>
        </LinearGradientBrush>-->
        <ImageBrush x:Key="CaptionBackground" 
                    ImageSource="pack://application:,,,/XLY.Framework.WPFTest;component/Images/back/b2.jpg"  Opacity="1"
                    Viewport="0,0,202,143" ViewportUnits="Absolute" TileMode="Tile" AlignmentX="Left" AlignmentY="Top"/>
        
        <!--MessageBoxX-->
        <SolidColorBrush x:Key="InfoForeground" Color="White"></SolidColorBrush>
        <SolidColorBrush x:Key="QuestionForeground" Color="#74B80C"></SolidColorBrush>
        <SolidColorBrush x:Key="WarningForeground" Color="DarkOrange"></SolidColorBrush>
        <SolidColorBrush x:Key="ErrorForeground" Color="#E74E4E"></SolidColorBrush>
        <!--WaitingBox-->
        <SolidColorBrush x:Key="WaitingBoxBackground" Color="#921692"></SolidColorBrush>
        <!--边框:Menu-->
        <DropShadowEffect x:Key="DefaultDropShadow" Color="Black" BlurRadius="5" ShadowDepth="2" Direction="315" Opacity="0.6" />
        <!--输入组件-->
        <SolidColorBrush x:Key="TextForeground" Color="White"></SolidColorBrush>
        <SolidColorBrush x:Key="TextBackground" Color="#0D234B"></SolidColorBrush>
        <SolidColorBrush x:Key="TextSelectionBrush" Color="#8F8787"></SolidColorBrush>
        <!--TextBox默认Label颜色-->
        <SolidColorBrush x:Key="TextLabelBackground" Color="#508AB6"></SolidColorBrush>
        <!--输入框-->
        <SolidColorBrush x:Key="ControlBorderBrush" Color="#999C9F"></SolidColorBrush>
        <SolidColorBrush x:Key="MouseOverBorderBrush" Color="#F6D1D1"></SolidColorBrush>
        <SolidColorBrush x:Key="FocusBackground" Color="#365080"></SolidColorBrush>
        <SolidColorBrush x:Key="FocusBorderBrush" Color="#EBCECE"></SolidColorBrush>
        <!--ScrollBar-->
        <SolidColorBrush x:Key="ScrollBarForeround" Color="#877F7F"></SolidColorBrush>
        <SolidColorBrush x:Key="ScrollBarBackground" Color="#3E3E42"></SolidColorBrush>
    
        <!--ItemsControl:DataGrid,Tree-->
        <sys:Double x:Key="HeaderFontSize">14</sys:Double>
        <SolidColorBrush x:Key="HeaderBorderBrush" Color="#A6FFA500"></SolidColorBrush>
        <SolidColorBrush x:Key="HeaderBackground" Color="#0A48D3"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemsContentBackground" Color="#1389D7"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemsAlternationContentBackground" Color="#128EE0"></SolidColorBrush>
        <SolidColorBrush x:Key="GridLinesBrush" Color="#A6D0C2A7"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemSelectedForeground" Color="White"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemSelectedBackground" Color="#A145F8"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemMouseOverBackground" Color="#BA7DF4"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemMouseOverForeground" Color="White"></SolidColorBrush>
        <!--高亮:日历Today-->
        <SolidColorBrush x:Key="ItemHighlighteBackground" Color="Blue"></SolidColorBrush>
        <SolidColorBrush x:Key="ItemHighlighteForeground" Color="White"></SolidColorBrush>
    
        <!--普通无背景按钮-->
        <SolidColorBrush x:Key="CheckedForeground" Color="#F7B63E"></SolidColorBrush>
        <SolidColorBrush x:Key="MouseOverForeground" Color="Orange"></SolidColorBrush>
        <SolidColorBrush x:Key="PressedForeground" Color="DarkOrange"></SolidColorBrush>
        <SolidColorBrush x:Key="LinkForeground" Color="#0816BB"></SolidColorBrush>
        <!--Popup,ComboBox-->
        <SolidColorBrush x:Key="PopupBackground" Color="#066EB3"></SolidColorBrush>
        <!--Button-->
        <SolidColorBrush x:Key="ButtonBackground" Color="#1D4A9A"></SolidColorBrush>
        <SolidColorBrush x:Key="ButtonForeground" Color="White"></SolidColorBrush>
        <SolidColorBrush x:Key="ButtonMouseOverBackground" Color="Orange"></SolidColorBrush>
        <SolidColorBrush x:Key="ButtonMouseOverForeground" Color="White"></SolidColorBrush>
        <SolidColorBrush x:Key="ButtonPressedBackground" Color="DarkOrange"></SolidColorBrush>
        <SolidColorBrush x:Key="ButtonPressedForeground" Color="White"></SolidColorBrush>
        <!--Menu-->
        <SolidColorBrush x:Key="MenuForeground" Color="#920892"></SolidColorBrush>
        <SolidColorBrush x:Key="MenuBackground" Color="#DDD1D1"></SolidColorBrush>
        <SolidColorBrush x:Key="MenuBorderBrush" Color="DarkBlue"></SolidColorBrush>
        <SolidColorBrush x:Key="MenuMouseOverBackground" Color="#0D3CD2"></SolidColorBrush>
        <SolidColorBrush x:Key="MenuMouseOverForeground" Color="White"></SolidColorBrush>
        <SolidColorBrush x:Key="MenuPressedBackground" Color="#082CA0"></SolidColorBrush>
        <SolidColorBrush x:Key="MenuPressedForeground" Color="White"></SolidColorBrush>
        <!--State brush-->
        <SolidColorBrush x:Key="SuccessfulfaiBrush" Color="#16B32A"></SolidColorBrush>
        <SolidColorBrush x:Key="FailedBrush" Color="#B92222"></SolidColorBrush>
    
        <FontFamily x:Key="FontFamily" >Microsoft YaHei</FontFamily>
        <sys:Double x:Key="FontSize">13</sys:Double>
        <sys:Double x:Key="DisableOpacity">0.5</sys:Double>
        <sys:Double x:Key="ReadonlyOpacity">0.88</sys:Double>
        <sys:Double x:Key="WatermarkOpacity">0.4</sys:Double>
        <sys:String x:Key="DateFormat">yyyy年MM月dd日</sys:String>
        <sys:String x:Key="DateTimeFormat">yyyy-MM-dd HH:mm:ss</sys:String>
    
    </ResourceDictionary>

    2.4转换器

      BackgroundToForegroundConverter.cs代码:  

        /// <summary>
        /// 根据背景色获取前景色。当然也可反着用
        /// </summary>
        public class BackgroundToForegroundConverter : IValueConverter
        {
            private Color IdealTextColor(Color bg)
            {
                const int nThreshold = 105;
                var bgDelta = System.Convert.ToInt32((bg.R * 0.299) + (bg.G * 0.587) + (bg.B * 0.114));
                var foreColor = (255 - bgDelta < nThreshold) ? Colors.Black : Colors.White;
                return foreColor;
            }
    
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                if (value is SolidColorBrush)
                {
                    var idealForegroundColor = this.IdealTextColor(((SolidColorBrush)value).Color);
                    var foreGroundBrush = new SolidColorBrush(idealForegroundColor);
                    foreGroundBrush.Freeze();
                    return foreGroundBrush;
                }
                return Brushes.White;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return DependencyProperty.UnsetValue;
            }
        }

      PercentToAngleConverter.cs代码:  

        /// <summary>
        /// 百分比转换为角度值
        /// </summary>
        public class PercentToAngleConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var percent = value.ToSafeString().ToDouble();
                if (percent >= 1) return 360.0D;
                return percent * 360;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

      ThicknessToDoubleConverter.cs代码:  

        /// <summary>
        /// 获取Thickness固定值double
        /// </summary>
        public class ThicknessToDoubleConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var thickness = (Thickness)value;
                return thickness.Left;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return DependencyProperty.UnsetValue;
            }
        }

      TreeViewMarginConverter.cs代码:  

       /// <summary>
        /// 计算树节点的左缩进位置
        /// </summary>
        public class TreeViewMarginConverter : IValueConverter
        {
            public double Length { get; set; }
    
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var item = value as TreeViewItem;
                if (item == null)
                    return new Thickness(0);
                int dep = this.GetDepth(item);
                return new Thickness(Length * dep, 0, 0, 0);
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                return DependencyProperty.UnsetValue;
            }
    
            public int GetDepth(TreeViewItem item)
            {
                TreeViewItem parent;
                while ((parent = GetParent(item)) != null)
                {
                    return GetDepth(parent) + 1;
                }
                return 0;
            }
    
            private TreeViewItem GetParent(TreeViewItem item)
            {
                var parent = item != null ? VisualTreeHelper.GetParent(item) : null;
                while (parent != null && !(parent is TreeViewItem || parent is TreeView))
                {
                    parent = VisualTreeHelper.GetParent(parent);
                }
                return parent as TreeViewItem;
            }
        }

      TrueToFalseConverter.cs代码:  

        /// <summary>
        /// 这是一个颠倒黑白的世界
        /// </summary>
        public sealed class TrueToFalseConverter : IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var v = (bool)value;
                return !v;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {
                throw new NotImplementedException();
            }
        }

      为了使用简单,对常用的转换器定义了静态变量的引用:  

        /// <summary>
        /// 常用转换器的静态引用
        /// 使用实例:Converter={x:Static local:XConverter.TrueToFalseConverter}
        /// </summary>
        public sealed class XConverter
        {
            public static BooleanToVisibilityConverter BooleanToVisibilityConverter
            {
                get { return Singleton<BooleanToVisibilityConverter>.GetInstance(); }
            }
    
            public static TrueToFalseConverter TrueToFalseConverter
            {
                get { return Singleton<TrueToFalseConverter>.GetInstance(); }
            }
    
            public static ThicknessToDoubleConverter ThicknessToDoubleConverter
            {
                get { return Singleton<ThicknessToDoubleConverter>.GetInstance(); }
            }
            public static BackgroundToForegroundConverter BackgroundToForegroundConverter
            {
                get { return Singleton<BackgroundToForegroundConverter>.GetInstance(); }
            }
            public static TreeViewMarginConverter TreeViewMarginConverter
            {
                get { return Singleton<TreeViewMarginConverter>.GetInstance(); }
            }
    
            public static PercentToAngleConverter PercentToAngleConverter
            {
                get { return Singleton<PercentToAngleConverter>.GetInstance(); }
            }
        }

      然后使用时就不用在xaml中声明资源了,通过静态引用的方式使用,就是这样的: 

    EndAngle="{TemplateBinding Value, Converter={x:Static local:XConverter.PercentToAngleConverter}}"

     2.6其他样式

      Share.xaml:  

        <!--下拉按钮样式:ToggleButton样式  ['tɑɡl] 开关,触发器;拴扣;[船] 套索钉-->
        <!--图标大小:local:ControlAttachProperty.FIconSize-->
        <!--图标边距:local:ControlAttachProperty.FIconMargin-->
        <!--图标:local:ControlAttachProperty.FIcon-->
        <Style TargetType="{x:Type ToggleButton}" x:Key="ComboToggleButton">
            <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
            <Setter Property="local:ControlAttachProperty.FIconSize" Value="18"/>
            <Setter Property="local:ControlAttachProperty.FIconMargin" Value="0,1,3,1"/>
            <Setter Property="local:ControlAttachProperty.FIcon" Value="&#xe665;"/>
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Grid x:Name="Grid">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="Auto"/>
                            </Grid.ColumnDefinitions>
                            <Border Background="{TemplateBinding Background}" x:Name="Bg" Grid.ColumnSpan="2" Margin="0,1,1,1"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"  Opacity="0.3"/>
                            <TextBlock Grid.Column="1" x:Name="FIcon" FontSize="{Binding Path=(local:ControlAttachProperty.FIconSize),RelativeSource={RelativeSource TemplatedParent}}"
                                       Text="{TemplateBinding local:ControlAttachProperty.FIcon}" 
                                       local:ControlAttachProperty.AllowsAnimation="{TemplateBinding IsChecked}"
                                       Foreground="{TemplateBinding Foreground}" Style="{StaticResource FIcon}"
                                       Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}"/>
                        </Grid>
                        <!--z触发器-->
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}" />
                                <Setter Property="Opacity" TargetName="Bg" Value="0.55" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
                                <Setter Property="Opacity" TargetName="Bg" Value="0.6" />
                            </Trigger>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
                                <Setter Property="Opacity" TargetName="Bg" Value="0.6" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <!--编辑状态文本框样式-->
        <Style TargetType="{x:Type TextBox}" x:Key="EditableTextBoxStyle">
            <Setter Property="Margin" Value="1"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="BorderThickness" Value="0"/>
            <Setter Property="Background" Value="{x:Null}"/>
            <Setter Property="MaxLength" Value="2048"/>
            <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
            <Setter Property="ContextMenu" Value="{DynamicResource TextBoxContextMenu}" />
            <Setter Property="SelectionBrush" Value="{StaticResource TextSelectionBrush}" />
            <Setter Property="FontSize" Value="{StaticResource FontSize}"></Setter>
            <Setter Property="FontFamily" Value="{StaticResource FontFamily}"></Setter>
            <Setter Property="Focusable" Value="True"/>
            <Setter Property="CaretBrush" Value="{StaticResource TextForeground}" />
            <Setter Property="VerticalAlignment" Value="Center" />
            <Setter Property="SnapsToDevicePixels" Value="True"></Setter>
            <Style.Triggers>
                <Trigger Property="IsReadOnly" Value="True">
                    <Setter Property="Opacity" Value="{StaticResource ReadonlyOpacity}"></Setter>
                </Trigger>
                <Trigger Property="IsEnabled" Value="False">
                    <Setter Property="Opacity" Value="{StaticResource DisableOpacity}"></Setter>
                </Trigger>
            </Style.Triggers>
        </Style>
    View Code

      Global.xaml  

        <!--TextBlock-->
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
            <Setter Property="FontFamily" Value="{StaticResource FontFamily}"/>
            <Setter Property="FontSize" Value="{StaticResource FontSize}"/>
        </Style>
    
        <!--ToolTip-->
        <Style TargetType="{x:Type ToolTip}">
            <Setter Property="Foreground" Value="{StaticResource TextForeground}"/>
            <Setter Property="FontFamily" Value="{StaticResource FontFamily}"/>
            <Setter Property="FontSize" Value="{StaticResource FontSize}"/>
            <Setter Property="Background" Value="{StaticResource HeaderBackground}"/>
            <Setter Property="BorderBrush" Value="{StaticResource FocusBorderBrush}"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToolTip}">
                        <Border CornerRadius="2" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Background="{TemplateBinding Background}">
                            <ContentPresenter Margin="8,5,8,5"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>

      TablControl 的样式,TablControl.xaml  

        <Style x:Key="FIconTabItemStyle" TargetType="{x:Type TabItem}">
            <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
            <Setter Property="VerticalContentAlignment" Value="Stretch"/>
            <Setter Property="Background" Value="{StaticResource ButtonBackground}"/>
            <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
            <Setter Property="local:ControlAttachProperty.FIcon" Value="&#xe618;"/>
            <Setter Property="local:ControlAttachProperty.FIconSize" Value="26"/>
            <Setter Property="local:ControlAttachProperty.CornerRadius" Value="0"/>
            <Setter Property="local:ControlAttachProperty.FIconMargin" Value="0,0,2,0"/>
            <Setter Property="local:ControlAttachProperty.FocusBackground" Value="{StaticResource ButtonPressedBackground}"/>
            <Setter Property="local:ControlAttachProperty.FocusForeground" Value="{StaticResource ButtonMouseOverForeground}"/>
            <Setter Property="local:ControlAttachProperty.MouseOverBackground" Value="{StaticResource ButtonMouseOverBackground}"/>
            <Setter Property="local:ControlAttachProperty.MouseOverForeground" Value="{StaticResource ButtonPressedForeground}"/>
            <Setter Property="MinHeight" Value="20"/>
            <Setter Property="MinWidth" Value="20"/>
            <Setter Property="Margin" Value="0"/>
            <Setter Property="Padding" Value="3"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabItem}">
                        <Border x:Name="border" Margin="{TemplateBinding Margin}" SnapsToDevicePixels="True" ToolTip="{TemplateBinding ToolTip}"
                                CornerRadius="{TemplateBinding local:ControlAttachProperty.CornerRadius}"  Background="{TemplateBinding Background}">
                            <StackPanel VerticalAlignment="Center" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Orientation="Horizontal">
                                <TextBlock Style="{StaticResource FIcon}" Text="{TemplateBinding local:ControlAttachProperty.FIcon}" Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}"
                                           FontSize="{TemplateBinding local:ControlAttachProperty.FIconSize}" Foreground="{TemplateBinding Foreground}"/>
                                <TextBlock x:Name="txtheader" VerticalAlignment="Center"  Text="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}"/>
                            </StackPanel>
                        </Border>
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter  Property="Background" Value="{Binding Path=(local:ControlAttachProperty.MouseOverBackground),RelativeSource={RelativeSource Self}}"/>
                                <Setter  Property="Foreground" Value="{Binding Path=(local:ControlAttachProperty.MouseOverForeground),RelativeSource={RelativeSource Self}}"/>
                            </Trigger>
                            <Trigger Property="IsSelected" Value="true">
                                <Setter  Property="Background" Value="{Binding Path=(local:ControlAttachProperty.FocusBackground),RelativeSource={RelativeSource Self}}"/>
                                <Setter  Property="Foreground" Value="{Binding Path=(local:ControlAttachProperty.FocusForeground),RelativeSource={RelativeSource Self}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <Style x:Key="LeftTabControl" TargetType="{x:Type TabControl}">
            <Setter Property="Padding" Value="0"/>
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="BorderThickness" Value="1" />
            <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" />
            <Setter Property="ItemContainerStyle" Value="{DynamicResource FIconTabItemStyle}"/>
            <Setter Property="TabStripPlacement" Value="Left"></Setter>
            <Setter Property="local:ControlAttachProperty.FocusBackground" Value="{StaticResource ButtonPressedBackground}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid x:Name="PART_Root" Margin="{TemplateBinding Padding}" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="Auto"/>
                                <ColumnDefinition Width="*"/>
                            </Grid.ColumnDefinitions>
    
                            <Border BorderBrush="{TemplateBinding local:ControlAttachProperty.FocusBackground}" BorderThickness="0,0,2,0" >
                                <StackPanel x:Name="HeaderPanel" Margin="0,5,0,5" Orientation="Vertical" IsItemsHost="True" ></StackPanel>
                            </Border>
    
                            <Border x:Name="ContentPanel" Grid.Column="1" BorderBrush="{TemplateBinding BorderBrush}" 
                                    BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
                                        KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" 
                                        KeyboardNavigation.TabNavigation="Local" Width="Auto">
                                <ContentPresenter ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Width="Auto" />
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
     
        <Style x:Key="TopTabControl" TargetType="{x:Type TabControl}">
            <Setter Property="Padding" Value="0"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="Background" Value="Transparent" />
            <Setter Property="HorizontalContentAlignment" Value="Center"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="ItemContainerStyle" Value="{StaticResource FIconTabItemStyle}"/>
            <Setter Property="BorderBrush" Value="{StaticResource ControlBorderBrush}" />
            <Setter Property="TabStripPlacement" Value="Top"></Setter>
            <Setter Property="local:ControlAttachProperty.FocusBackground" Value="{StaticResource ButtonPressedBackground}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type TabControl}">
                        <Grid x:Name="PART_Root" Margin="{TemplateBinding Padding}" >
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="*"/>
                            </Grid.RowDefinitions>
    
                            <Border BorderBrush="{TemplateBinding local:ControlAttachProperty.FocusBackground}" BorderThickness="0,0,0,2" >
                                <StackPanel x:Name="HeaderPanel" Margin="5,0,5,0" Orientation="Horizontal" IsItemsHost="True" ></StackPanel>
                            </Border>
    
                            <Border x:Name="ContentPanel" Grid.Row="1" BorderBrush="{TemplateBinding BorderBrush}" 
                                    BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}"
                                        KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" 
                                        KeyboardNavigation.TabNavigation="Local" Width="Auto">
                                <ContentPresenter ContentSource="SelectedContent" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" Width="Auto"/>
                            </Border>
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    View Code

       ToggleButton的样式资源

    <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                        xmlns:local="clr-namespace:XLY.Framework.Controls"
                        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
        
        <Style TargetType="{x:Type ToggleButton}" x:Key="DefaultToggleButton">
            <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Grid x:Name="Grid" Margin="{TemplateBinding Padding}">
                            <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/>
                        </Grid>
                        <!--z触发器-->
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
                            </Trigger>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
        <Style TargetType="{x:Type ToggleButton}" x:Key="FIconToggleButton">
            <Setter Property="Foreground" Value="{StaticResource TextForeground}" />
            <Setter Property="local:ControlAttachProperty.FIconSize" Value="20"/>
            <Setter Property="local:ControlAttachProperty.FIconMargin" Value="1"/>
            <Setter Property="local:ControlAttachProperty.FIcon" Value="&#xe664;"/>
            <Setter Property="SnapsToDevicePixels" Value="True" />
            <Setter Property="Padding" Value="0" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type ToggleButton}">
                        <Grid x:Name="Grid" Margin="{TemplateBinding Padding}">
                            <TextBlock x:Name="FIcon" FontSize="{Binding Path=(local:ControlAttachProperty.FIconSize),RelativeSource={RelativeSource TemplatedParent}}"
                                       Text="{TemplateBinding local:ControlAttachProperty.FIcon}" 
                                       Foreground="{TemplateBinding Foreground}" Style="{StaticResource FIcon}"
                                       Margin="{TemplateBinding local:ControlAttachProperty.FIconMargin}"/>
                        </Grid>
                        <!--z触发器-->
                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource MouseOverForeground}" />
                            </Trigger>
                            <Trigger Property="IsPressed" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
                            </Trigger>
                            <Trigger Property="IsChecked" Value="True">
                                <Setter Property="Foreground" Value="{StaticResource PressedForeground}" />
                            </Trigger>
                            <Trigger Property="IsEnabled" Value="false">
                                <Setter Property="Opacity" Value="{StaticResource DisableOpacity}" TargetName="Grid"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    
    </ResourceDictionary>
    View Code

     Github项目地址https://github.com/kwonganding/wpf.controls

    版权所有,文章来源:http://www.cnblogs.com/anding

    个人能力有限,本文内容仅供学习、探讨,欢迎指正、交流。

  • 相关阅读:
    HDU 2899 Strange fuction
    HDU 2899 Strange fuction
    HDU 2199 Can you solve this equation?
    HDU 2199 Can you solve this equation?
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 700 二叉搜索树中的搜索(遍历树)
    Java实现 LeetCode 699 掉落的方块(线段树?)
    Java实现 LeetCode 699 掉落的方块(线段树?)
    Java实现 LeetCode 699 掉落的方块(线段树?)
  • 原文地址:https://www.cnblogs.com/anding/p/5018363.html
Copyright © 2011-2022 走看看