可关闭TabItem的Header:
前台代码:
<UserControl x:Class="CloseableTabItem_Test.CloseableTabItemHeader"
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">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Name="columnLabel" Width="*"></ColumnDefinition>
<ColumnDefinition Name="columnCloseButton" Width="20"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Name="lblTitle" Grid.Column="0" Style="{StaticResource CloseableTabItemLabel_RD}"/>
<Button Name="btnClose" Grid.Column="1" FontFamily="Courier" FontWeight="Bold" Style="{StaticResource CloseableTabItemButton_RD}"/>
</Grid>
</UserControl>
后台代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 CloseableTabItem_Test
{
/// <summary>
/// CloseableTabItemHeader.xaml 的交互逻辑
/// </summary>
public partial class CloseableTabItemHeader : UserControl
{
/// <summary>
/// 实例化可关闭标签项
/// </summary>
public CloseableTabItemHeader()
{
InitializeComponent();
Title = lblTitle.Content as string;
}
/// <summary>
/// 实例化可关闭标签项(给定标题文本)
/// </summary>
/// <param name="title">Title</param>
public CloseableTabItemHeader(string title)
{
InitializeComponent();
Title = title;
}
// 可关闭标签项文本
private string _title;
/// <summary>
/// 设置标题
/// </summary>
public string Title
{
get { return _title; }
set
{
_title = value;
lblTitle.Content = _title;
}
}
}
}
资源字典以及App.xml的设置:
CloseableTabStyle.xaml中:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--Header中的文字Label样式-->
<Style x:Key="CloseableTabItemLabel_RD" TargetType="Label">
<Setter Property="Foreground" Value="White" />
</Style>
<!--Header中的Button样式-->
<Style x:Key="CloseableTabItemButton_RD" TargetType="Button">
<Setter Property="Foreground" Value="White" />
<Setter Property="FontFamily" Value="Courier" />
<Setter Property="FontWeight" Value="Bold" />
<Setter Property="FontStretch" Value="Normal" />
<Setter Property="FontSize" Value="14" />
<Setter Property="Padding" Value="0" />
<Setter Property="ToolTip" Value="Close" />
<Setter Property="Content" Value="×" />
<Setter Property="Height" Value="20" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" Background="#00000000" SnapsToDevicePixels="true">
<ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" TargetName="border" Value="#B3CA0300" />
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="border" Value="#F0CA0300" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!--TabItem样式-->
<Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="Background" Value="#0082BC" />
<Setter Property="Foreground" Value="Black"/>
<Setter Property="Padding" Value="6,1,6,1"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid SnapsToDevicePixels="true">
<Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="1,1,1,0" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}">
<ContentPresenter x:Name="Content" ContentSource="Header" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Background" TargetName="Bd" Value="#FF8C05"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="#3FA1CD"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="IsMouseOver" Value="true"/>
</MultiTrigger.Conditions>
<Setter Property="Background" TargetName="Bd" Value="#FFA337"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Top"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-2,-1"/>
<Setter Property="Margin" TargetName="Content" Value="0,0,0,1"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Bottom"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-1,-2,-2"/>
<Setter Property="Margin" TargetName="Content" Value="0,1,0,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Left"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-2,-2,-1,-2"/>
<Setter Property="Margin" TargetName="Content" Value="0,0,1,0"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Property="TabStripPlacement" Value="Right"/>
</MultiTrigger.Conditions>
<Setter Property="Margin" Value="-1,-2,-2,-2"/>
<Setter Property="Margin" TargetName="Content" Value="1,0,0,0"/>
</MultiTrigger>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
App.xml中:
<Application x:Class="CloseableTabItem_Test.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="MainWindow.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="CloseableTabStyle.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
可关闭TabItem的代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace CloseableTabItem_Test
{
/// <summary>
/// 是否自动排序
/// </summary>
public enum SortWay
{
IsAutoSort, NotSort
}
public class CloseableTabItem : TabItem
{
/// <summary>
///
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public delegate void CloseButtonDelegate(object sender, RoutedEventArgs e);
/// <summary>
/// 选项卡TabItem关闭时事件
/// </summary>
public event RoutedEventHandler TabItemClosing;
/// <summary>
/// 实例化标签项
/// </summary>
public CloseableTabItem()
: this("New tab")
{ }
/// <summary>
/// 实例化标签项(给定标题)
/// </summary>
/// <param name="title">新标签项的标题字符串</param>
public CloseableTabItem(string title)
: this(title, SortWay.NotSort)
{
}
/// <summary>
/// 实例化标签项(给定标题,给定是否自动排序)
/// </summary>
/// <param name="title">标题</param>
/// <param name="isAutoSort">是否自动排序</param>
public CloseableTabItem(string title, SortWay sortWay)
{
//设定样式
this.Style = (Style)Application.Current.Resources["TabItemStyle"];
//生产一个可关闭的Header
CloseableTabItemHeader ctih = createCloseableTabItem();
//自动排序
switch (sortWay)
{
case SortWay.IsAutoSort:
break;
case SortWay.NotSort:
break;
default:
break;
}
//设定标题
ctih.Title = title;
//设定Header
this.Header = ctih;
}
/// <summary>
/// 创建一个标签页头
/// </summary>
/// <returns>标签页头(自定义控件)</returns>
private CloseableTabItemHeader createCloseableTabItem()
{
//实例化一个Header
CloseableTabItemHeader ctih = new CloseableTabItemHeader();
//添加关闭按钮点击事件
ctih.btnClose.Click += new RoutedEventHandler(btnClose_Click);
//返回Header
return ctih;
}
/// <summary>
/// 关闭按钮的点击事件处理方法
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void btnClose_Click(object sender, RoutedEventArgs e)
{
// 触发标签项关闭事件
if (TabItemClosing != null)
{
TabItemClosing.Invoke(sender, e);
}
//关闭当前TabItem
((TabControl)GetParentObject<TabControl>(this)).Items.Remove(this);
}
/// 获得指定元素的父元素
/// </summary>
/// <typeparam name="T">父级元素类型</typeparam>
/// <param name="obj">指定查找元素</param>
/// <returns></returns>
public T GetParentObject<T>(DependencyObject obj) where T : FrameworkElement
{
//返回可视对象的父对象
DependencyObject parent = VisualTreeHelper.GetParent(obj);
//按层、类型提取父级
while (parent != null)
{
if (parent is T)
return (T)parent;
parent = VisualTreeHelper.GetParent(parent);
}
//返回
return null;
}
}
}
测试:
MainWindow.xaml中:
<Window x:Class="CloseableTabItem_Test.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
<Grid Name="grid">
<TabControl Name="tabControl_Grid" TabStripPlacement="Top"/>
</Grid>
</Window>
MainWindow.cs中:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
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 CloseableTabItem_Test
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
Button button = new Button();
button.Background = Brushes.Aqua;
button.Content = "+1";
button.Width = 50;
button.Height = 20;
button.HorizontalAlignment = System.Windows.HorizontalAlignment.Right;
button.VerticalAlignment = System.Windows.VerticalAlignment.Bottom;
button.Margin = new Thickness(0,0,50,50);
button.Click += button_Click;
grid.Children.Add(button);
}
private void button_Click(object sender, RoutedEventArgs e)
{
tabControl_Grid.Items.Add(new CloseableTabItem("名都不给,你得多懒."));
}
}
}
转载请注明出处,谢谢。