WPF如何自定义TabControl控件样式示例详解

一、前言

程序中经常会用到TabControl控件,默认的控件样式很普通。而且样式或功能不一定符合我们的要求。比如:我们需要TabControl的标题能够居中、或平均分布;或者我们希望TabControl的标题能够进行关闭。要实现这些功能我们需要对TabControl的样式进行定义。

二、实现TabControl的标题平均分布

默认的TabControl标题是使用TabPanel容器包含的。要想实现TabControl标题头平均分布,需要把TabPanel替换成UniformGrid;

替换后的TabControl样式如下:

即使这样设置了,TabControl的标题还是很丑,这个时候就需要通过设置TabItem来更改标题样式了。

TabItem样式如下:

至此,样式已经设置完毕,引用示例:


  
   
   
    
   
   
   
   
    
   
   
  
  

效果如下:

WPF如何自定义TabControl控件样式示例详解_第1张图片

三、实现TabControl标题居中显示(不平均分布)

同理需要更改TabControl的样式和TabItem的样式。需要把使用TabPanel作为标题的容器,设置HorizontalAlignment为Center;

TabControl的样式如下:

TabItem样式如下:

引用示例:


    
     
      
       
      
     
     
      
       
      
     
    
   

效果如下:

WPF如何自定义TabControl控件样式示例详解_第2张图片

四、带关闭按钮的TabControl

带关闭按钮的TabControl其实就是就是扩展TabItem,需要新建WPF自定义控件,命名为TabItemClose吧;

C#代码如下:

public class TabItemClose : TabItem
 {
  static TabItemClose()
  {
   DefaultStyleKeyProperty.OverrideMetadata(typeof(TabItemClose), new FrameworkPropertyMetadata(typeof(TabItemClose)));
  }

  private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
   d.SetValue(e.Property, e.NewValue);
  }

  /// 
  /// 是否可以关闭
  /// 
  public bool IsCanClose
  {
   get { return (bool)GetValue(IsCanCloseProperty); }
   set { SetValue(IsCanCloseProperty, value); }
  }

  public static readonly DependencyProperty IsCanCloseProperty =
   DependencyProperty.Register("IsCanClose", typeof(bool), typeof(TabItemClose), new PropertyMetadata(true, OnPropertyChanged));

  /// 
  /// 关闭的图标
  /// 
  public ImageSource CloseIcon
  {
   get { return (ImageSource)GetValue(CloseIconProperty); }
   set { SetValue(CloseIconProperty, value); }
  }

  public static readonly DependencyProperty CloseIconProperty =
   DependencyProperty.Register("CloseIcon", typeof(ImageSource), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));



  /// 
  /// 正常背景色
  /// 
  public SolidColorBrush NormalBackground
  {
   get { return (SolidColorBrush)GetValue(NormalBackgroundProperty); }
   set { SetValue(NormalBackgroundProperty, value); }
  }

  public static readonly DependencyProperty NormalBackgroundProperty =
   DependencyProperty.Register("NormalBackground", typeof(SolidColorBrush), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));

  /// 
  /// 悬浮背景色
  /// 
  public SolidColorBrush OverBackgound
  {
   get { return (SolidColorBrush)GetValue(OverBackgoundProperty); }
   set { SetValue(OverBackgoundProperty, value); }
  }

  public static readonly DependencyProperty OverBackgoundProperty =
   DependencyProperty.Register("OverBackgound", typeof(SolidColorBrush), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));


  /// 
  /// 选中背景色
  /// 
  public SolidColorBrush SelectedBackgound
  {
   get { return (SolidColorBrush)GetValue(SelectedBackgoundProperty); }
   set { SetValue(SelectedBackgoundProperty, value); }
  }

  public static readonly DependencyProperty SelectedBackgoundProperty =
   DependencyProperty.Register("SelectedBackgound", typeof(SolidColorBrush), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));


  /// 
  /// 默认前景色
  /// 
  public SolidColorBrush NormalForeground
  {
   get { return (SolidColorBrush)GetValue(NormalForegroundProperty); }
   set { SetValue(NormalForegroundProperty, value); }
  }

  public static readonly DependencyProperty NormalForegroundProperty =
   DependencyProperty.Register("NormalForeground", typeof(SolidColorBrush), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));

  /// 
  /// 悬浮前景色
  /// 
  public SolidColorBrush OverForeground
  {
   get { return (SolidColorBrush)GetValue(OverForegroundProperty); }
   set { SetValue(OverForegroundProperty, value); }
  }

  public static readonly DependencyProperty OverForegroundProperty =
   DependencyProperty.Register("OverForeground", typeof(SolidColorBrush), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));

  /// 
  /// 选中前景色
  /// 
  public SolidColorBrush SelectedForeground
  {
   get { return (SolidColorBrush)GetValue(SelectedForegroundProperty); }
   set { SetValue(SelectedForegroundProperty, value); }
  }

  public static readonly DependencyProperty SelectedForegroundProperty =
   DependencyProperty.Register("SelectedForeground", typeof(SolidColorBrush), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));
  /// 
  /// 控件圆角
  /// 
  public CornerRadius CornerRadius
  {
   get { return (CornerRadius)GetValue(CornerRadiusProperty); }
   set { SetValue(CornerRadiusProperty, value); }
  }
  public static readonly DependencyProperty CornerRadiusProperty =
   DependencyProperty.Register("CornerRadius", typeof(CornerRadius), typeof(TabItemClose), new PropertyMetadata(new CornerRadius(0), OnPropertyChanged));
  /// 
  /// 前置Logo
  /// 
  public ImageSource LogoIcon
  {
   get { return (ImageSource)GetValue(LogoIconProperty); }
   set { SetValue(LogoIconProperty, value); }
  }
  public static readonly DependencyProperty LogoIconProperty =
   DependencyProperty.Register("LogoIcon", typeof(ImageSource), typeof(TabItemClose), new PropertyMetadata(null, OnPropertyChanged));
  /// 
  /// 前置Logo宽度
  /// 
  public double LogoIconWidth
  {
   get { return (double)GetValue(LogoIconWidthProperty); }
   set { SetValue(LogoIconWidthProperty, value); }
  }
  public static readonly DependencyProperty LogoIconWidthProperty =
   DependencyProperty.Register("LogoIconWidth", typeof(double), typeof(TabItemClose), new PropertyMetadata(double.Parse("0"), OnPropertyChanged));
  /// 
  /// 前置Logo高度
  /// 
  public double LogoIconHeigth
  {
   get { return (double)GetValue(LogoIconHeigthProperty); }
   set { SetValue(LogoIconHeigthProperty, value); }
  }
  public static readonly DependencyProperty LogoIconHeigthProperty =
   DependencyProperty.Register("LogoIconHeigth", typeof(double), typeof(TabItemClose), new PropertyMetadata(double.Parse("0"), OnPropertyChanged));
  /// 
  /// LogoPadding
  /// 
  public Thickness LogoPadding
  {
   get { return (Thickness)GetValue(LogoPaddingProperty); }
   set { SetValue(LogoPaddingProperty, value); }
  }

  public static readonly DependencyProperty LogoPaddingProperty =
   DependencyProperty.Register("LogoPadding", typeof(Thickness), typeof(TabItemClose), new PropertyMetadata(new Thickness(0), OnPropertyChanged));
  /// 
  /// 关闭item事件
  /// 
  public event RoutedEventHandler CloseItem
  {
   add { AddHandler(CloseItemEvent, value); }
   remove { RemoveHandler(CloseItemEvent, value); }
  }
  public static readonly RoutedEvent CloseItemEvent =
   EventManager.RegisterRoutedEvent("CloseItem", RoutingStrategy.Bubble, typeof(RoutedEventHandler), typeof(TabItemClose));
  /// 
  /// 关闭项的右键菜单
  /// 
  public ContextMenu ItemContextMenu { get; set; }

  Border ItemBorder;
  public override void OnApplyTemplate()
  {
   base.OnApplyTemplate();
   ItemBorder = Template.FindName("_bordertop", this) as Border;
   if (ItemContextMenu != null)
   {
    ItemBorder.ContextMenu = ItemContextMenu;
   }
  }
 }

这里面我们添加了很多扩展功能,包括右键菜单,图标显示和控件圆角,以及各种背景色属性。

然后为TabItemClose设置样式

这里面使用了一个close的图标

TabControl的图标可设置可不设置,看自己需要。

这里面还用到了前面讲的控件ButtonEx,定义方法我就不重复赘述了。大家可以通过这个链接跳转查看://www.jb51.net/article/138475.htm。ButtonEx.cs里面还要添加几个方法用来支持关闭TabItem:

protected override void OnClick()
  {
   base.OnClick();
   if (!string.IsNullOrEmpty(Name) && Name == "PART_Close_TabItem")
   {
    TabItemClose itemclose = FindVisualParent(this);
    (itemclose.Parent as TabControl).Items.Remove(itemclose);
    RoutedEventArgs args = new RoutedEventArgs(TabItemClose.CloseItemEvent, itemclose);
    itemclose.RaiseEvent(args);
   }
  }

  public static T FindVisualParent(DependencyObject obj) where T : class
  {
   while (obj != null)
   {
    if (obj is T)
     return obj as T;

    obj = VisualTreeHelper.GetParent(obj);
   }
   return null;
  }

引用示例:


    
     
      
       
      
     
     
      
       
      
     
    
   

效果如下:

WPF如何自定义TabControl控件样式示例详解_第3张图片

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

你可能感兴趣的:(WPF如何自定义TabControl控件样式示例详解)