WPF如何自定義TabControl控件樣式示例詳解
一、前言
程序中經常會用到TabControl控件,默認的控件樣式很普通。而且樣式或功能不一定符合我們的要求。比如:我們需要TabControl的標題能夠居中、或平均分布;或者我們希望TabControl的標題能夠進行關閉。要實現(xiàn)這些功能我們需要對TabControl的樣式進行定義。
二、實現(xiàn)TabControl的標題平均分布
默認的TabControl標題是使用TabPanel容器包含的。要想實現(xiàn)TabControl標題頭平均分布,需要把TabPanel替換成UniformGrid;
替換后的TabControl樣式如下:
<Style x:Key="TabControlStyle" TargetType="{x:Type TabControl}">
<Setter Property="Padding" Value="2"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="#FFACACAC"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="templateRoot" ClipToBounds="True" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<UniformGrid x:Name="HeaderPanel" Rows="1" Background="Transparent" Grid.Column="0" IsItemsHost="True" Margin="0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
<Line X1="0" X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" Stroke="White" StrokeThickness="0.1" VerticalAlignment="Bottom" Margin="0 0 0 1" SnapsToDevicePixels="True"/>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentTemplate="{TemplateBinding SelectedContentTemplate}" Content="{TemplateBinding SelectedContent}" ContentStringFormat="{TemplateBinding SelectedContentStringFormat}" ContentSource="SelectedContent" Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
即使這樣設置了,TabControl的標題還是很丑,這個時候就需要通過設置TabItem來更改標題樣式了。
TabItem樣式如下:
<Style x:Key="TabItemStyle" TargetType="{x:Type TabItem}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="#FFACACAC"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="True" Background="Transparent">
<TextBlock x:Name="txt" Visibility="Visible" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Header}" ToolTip="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}" TextTrimming="CharacterEllipsis" />
</Grid>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top"/>
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" TargetName="txt" Value="#fffea1"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Left"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Bottom"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Right"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top"/>
</MultiDataTrigger.Conditions>
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Foreground" TargetName="txt" Value="#fffea1"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
至此,樣式已經設置完畢,引用示例:
<Grid Background="#858586">
<TabControl Style="{StaticResource TabControlStyle}" Width="300" Height="200" Background="Transparent" BorderBrush="Transparent" BorderThickness="0">
<TabItem Style="{StaticResource TabItemStyle}" Cursor="Hand" Header="音樂電臺" Height="38" >
<Grid Background="#33ffffff">
<TextBlock Text="音樂電臺" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</TabItem>
<TabItem Style="{StaticResource TabItemStyle}" Cursor="Hand" Header="Mv電臺" Height="38" >
<Grid Background="#33ffffff">
<TextBlock Text="Mv電臺" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
效果如下:
三、實現(xiàn)TabControl標題居中顯示(不平均分布)
同理需要更改TabControl的樣式和TabItem的樣式。需要把使用TabPanel作為標題的容器,設置HorizontalAlignment為Center;
TabControl的樣式如下:
<Style x:Key="TabControlWithUnderLineStyle" TargetType="{x:Type TabControl}">
<Setter Property="Padding" Value="2"/>
<Setter Property="HorizontalContentAlignment" Value="Center"/>
<Setter Property="VerticalContentAlignment" Value="Center"/>
<Setter Property="Background" Value="White"/>
<Setter Property="BorderBrush" Value="#FFACACAC"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid x:Name="templateRoot" ClipToBounds="True" SnapsToDevicePixels="True" KeyboardNavigation.TabNavigation="Local">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="ColumnDefinition0"/>
<ColumnDefinition x:Name="ColumnDefinition1" Width="0"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition x:Name="RowDefinition0" Height="Auto"/>
<RowDefinition x:Name="RowDefinition1" Height="*"/>
</Grid.RowDefinitions>
<TabPanel x:Name="HeaderPanel" HorizontalAlignment="Center" Background="Transparent" Grid.Column="0" IsItemsHost="True" Margin="0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/>
<Line X1="0" X2="{Binding ActualWidth, RelativeSource={RelativeSource Self}}" Stroke="Gray" StrokeThickness="0.1" VerticalAlignment="Bottom" Margin="0 0 0 1" SnapsToDevicePixels="True"/>
<Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local">
<ContentPresenter x:Name="PART_SelectedContentHost" ContentTemplate="{TemplateBinding SelectedContentTemplate}" Content="{TemplateBinding SelectedContent}" ContentStringFormat="{TemplateBinding SelectedContentStringFormat}" ContentSource="SelectedContent" Margin="0" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="TabStripPlacement" Value="Bottom">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Left">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
</Trigger>
<Trigger Property="TabStripPlacement" Value="Right">
<Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/>
<Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/>
<Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/>
<Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/>
<Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/>
<Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/>
<Setter Property="Height" TargetName="RowDefinition0" Value="*"/>
<Setter Property="Height" TargetName="RowDefinition1" Value="0"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
TabItem樣式如下:
<Style x:Key="TabItemExWithUnderLineStyle" TargetType="{x:Type TabItem}">
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="BorderBrush" Value="#FFACACAC"/>
<Setter Property="Margin" Value="0"/>
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid x:Name="templateRoot" SnapsToDevicePixels="True" Background="Transparent">
<Border x:Name="_underline" BorderBrush="#37aefe" BorderThickness="0" Margin="{TemplateBinding Margin}"/>
<Grid>
<TextBlock x:Name="txt" Visibility="Visible" VerticalAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Header}" ToolTip="{TemplateBinding Header}" Foreground="{TemplateBinding Foreground}" TextTrimming="CharacterEllipsis" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsMouseOver, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top"/>
</MultiDataTrigger.Conditions>
<Setter Property="Foreground" TargetName="txt" Value="#37aefe"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Left"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Bottom"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Right"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsEnabled, RelativeSource={RelativeSource Self}}" Value="false"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top"/>
</MultiDataTrigger.Conditions>
<Setter Property="Opacity" TargetName="templateRoot" Value="0.56"/>
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding IsSelected, RelativeSource={RelativeSource Self}}" Value="true"/>
<Condition Binding="{Binding TabStripPlacement, RelativeSource={RelativeSource FindAncestor, AncestorLevel=1, AncestorType={x:Type TabControl}}}" Value="Top"/> </MultiDataTrigger.Conditions>
<Setter Property="Panel.ZIndex" Value="1"/>
<Setter Property="Foreground" TargetName="txt" Value="#37aefe"/>
<Setter Property="BorderThickness" TargetName="_underline" Value="0 0 0 2"/>
</MultiDataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
引用示例:
<Grid Background="#858586">
<TabControl Style="{StaticResource TabControlWithUnderLineStyle}" Foreground="Black" Width="300" Height="200" Background="Transparent" BorderBrush="Transparent" BorderThickness="0">
<TabItem Style="{StaticResource TabItemExWithUnderLineStyle}" Cursor="Hand" Header="音樂電臺" Height="38" Width="70" Margin="5 0">
<Grid Background="#33ffffff">
<TextBlock Text="音樂電臺" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</TabItem>
<TabItem Style="{StaticResource TabItemExWithUnderLineStyle}" Cursor="Hand" Header="Mv電臺" Height="38" Width="70" Margin="5 0">
<Grid Background="#33ffffff">
<TextBlock Text="Mv電臺" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</TabItem>
</TabControl>
</Grid>
效果如下:
四、帶關閉按鈕的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);
}
/// <summary>
/// 是否可以關閉
/// </summary>
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));
/// <summary>
/// 關閉的圖標
/// </summary>
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));
/// <summary>
/// 正常背景色
/// </summary>
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));
/// <summary>
/// 懸浮背景色
/// </summary>
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));
/// <summary>
/// 選中背景色
/// </summary>
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));
/// <summary>
/// 默認前景色
/// </summary>
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));
/// <summary>
/// 懸浮前景色
/// </summary>
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));
/// <summary>
/// 選中前景色
/// </summary>
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));
/// <summary>
/// 控件圓角
/// </summary>
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));
/// <summary>
/// 前置Logo
/// </summary>
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));
/// <summary>
/// 前置Logo寬度
/// </summary>
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));
/// <summary>
/// 前置Logo高度
/// </summary>
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));
/// <summary>
/// LogoPadding
/// </summary>
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));
/// <summary>
/// 關閉item事件
/// </summary>
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));
/// <summary>
/// 關閉項的右鍵菜單
/// </summary>
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設置樣式
<Style TargetType="{x:Type local:TabItemClose}">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
<Setter Property="Foreground" Value="#666666"/>
<Setter Property="Margin" Value="0 0 0 0"/>
<Setter Property="Padding" Value="0"/>
<Setter Property="BorderThickness" Value="0"/>
<Setter Property="CloseIcon" Value="/Images/close2.png"/>
<Setter Property="NormalBackground" Value="White"/>
<Setter Property="OverBackgound" Value="#33ca5100"/>
<Setter Property="SelectedBackgound" Value="#ca5100"/>
<Setter Property="NormalForeground" Value="#555558"/>
<Setter Property="OverForeground" Value="White"/>
<Setter Property="SelectedForeground" Value="White"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:TabItemClose}">
<Border x:Name="_bordertop" Width="{TemplateBinding Width}" MaxWidth="{TemplateBinding MaxWidth}" Height="{TemplateBinding Height}" CornerRadius="{TemplateBinding CornerRadius}" Background="{TemplateBinding NormalBackground}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" ToolTip="{TemplateBinding Header}" >
<DockPanel>
<Image x:Name="_logo" DockPanel.Dock="Left" Visibility="Visible" Margin="{TemplateBinding LogoPadding}" Source="{TemplateBinding LogoIcon}" VerticalAlignment="Center" HorizontalAlignment="Center" Stretch="Uniform" Width="{TemplateBinding LogoIconWidth}" Height="{TemplateBinding LogoIconHeigth}" />
<Grid Name="_grid" SnapsToDevicePixels="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition x:Name="_col_close" Width="20" />
</Grid.ColumnDefinitions>
<Border Grid.ColumnSpan="2" Background="White" Opacity="0"/>
<TextBlock x:Name="_txt" VerticalAlignment="Center" TextTrimming="CharacterEllipsis" Margin="3 0 3 0" Foreground="{TemplateBinding NormalForeground}" TextAlignment="Center" HorizontalAlignment="Center" Text="{TemplateBinding Header}" />
<Grid x:Name="_gridclose" Grid.Column="1" >
<Border x:Name="_borderbg" Background="Black" Opacity="0" />
<local:ButtonEx x:Name="PART_Close_TabItem" HorizontalAlignment="Center" VerticalAlignment="Center" Background="Transparent" Visibility="Visible" Icon="{TemplateBinding CloseIcon}" ButtonType="Icon" />
</Grid>
</Grid>
</DockPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="LogoIcon" Value="{x:Null}">
<Setter TargetName="_logo" Property="Visibility" Value="Collapsed" />
</Trigger>
<Trigger Property="IsCanClose" Value="false">
<Setter TargetName="_gridclose" Property="Visibility" Value="Collapsed"/>
<Setter TargetName="_col_close" Property="Width" Value="0"/>
</Trigger>
<Trigger Property="IsSelected" Value="true">
<Setter TargetName="_bordertop" Property="Background" Value="{Binding SelectedBackgound,RelativeSource={RelativeSource TemplatedParent}}" />
<Setter TargetName="_txt" Property="Foreground" Value="{Binding SelectedForeground,RelativeSource={RelativeSource TemplatedParent}}"/>
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="true"/>
<Condition Property="IsSelected" Value="false"/>
</MultiTrigger.Conditions>
<Setter TargetName="_txt" Property="Foreground" Value="{Binding OverForeground,RelativeSource={RelativeSource TemplatedParent}}"/>
<Setter TargetName="_bordertop" Property="Background" Value="{Binding OverBackgound,RelativeSource={RelativeSource TemplatedParent}}"/>
</MultiTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
這里面使用了一個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<TabItemClose>(this);
(itemclose.Parent as TabControl).Items.Remove(itemclose);
RoutedEventArgs args = new RoutedEventArgs(TabItemClose.CloseItemEvent, itemclose);
itemclose.RaiseEvent(args);
}
}
public static T FindVisualParent<T>(DependencyObject obj) where T : class
{
while (obj != null)
{
if (obj is T)
return obj as T;
obj = VisualTreeHelper.GetParent(obj);
}
return null;
}
引用示例:
<Grid Background="#858586">
<TabControl Foreground="Black" Width="300" Height="200" Background="Transparent" BorderBrush="Transparent" BorderThickness="0">
<local:TabItemClose Cursor="Hand" Header="音樂電臺" Height="20" Width="100">
<Grid Background="#aaffffff">
<TextBlock Text="音樂電臺" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</local:TabItemClose>
<local:TabItemClose Cursor="Hand" Header="Mv電臺" Height="20" Width="100">
<Grid Background="#aaffffff">
<TextBlock Text="Mv電臺" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</local:TabItemClose>
</TabControl>
</Grid>
效果如下:
總結
以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對我們的支持。
您可能感興趣的文章
- 01-10C#自定義簽名章實現(xiàn)方法
- 01-10WinForm實現(xiàn)自定義右下角提示效果的方法
- 01-10C#實現(xiàn)自定義windows系統(tǒng)日志的方法
- 01-10C#自定義事件監(jiān)聽實現(xiàn)方法
- 01-10Extjs4如何處理后臺json數(shù)據中日期和時間
- 01-10C#編程實現(xiàn)自定義熱鍵的方法
- 01-10asp.net中XML如何做增刪改查操作
- 01-10C#及WPF獲取本機所有字體和顏色的方法
- 01-10WPF實現(xiàn)類似360安全衛(wèi)士界面的程序源碼分享
- 01-10C#.NET中如何批量插入大量數(shù)據到數(shù)據庫中


閱讀排行
本欄相關
- 01-10C#通過反射獲取當前工程中所有窗體并
- 01-10關于ASP網頁無法打開的解決方案
- 01-10WinForm限制窗體不能移到屏幕外的方法
- 01-10WinForm繪制圓角的方法
- 01-10C#實現(xiàn)txt定位指定行完整實例
- 01-10WinForm實現(xiàn)仿視頻播放器左下角滾動新
- 01-10C#停止線程的方法
- 01-10C#實現(xiàn)清空回收站的方法
- 01-10C#通過重寫Panel改變邊框顏色與寬度的
- 01-10C#實現(xiàn)讀取注冊表監(jiān)控當前操作系統(tǒng)已
隨機閱讀
- 01-10delphi制作wav文件的方法
- 01-11Mac OSX 打開原生自帶讀寫NTFS功能(圖文
- 01-10C#中split用法實例總結
- 04-02jquery與jsp,用jquery
- 01-10使用C語言求解撲克牌的順子及n個骰子
- 08-05織夢dedecms什么時候用欄目交叉功能?
- 01-11ajax實現(xiàn)頁面的局部加載
- 01-10SublimeText編譯C開發(fā)環(huán)境設置
- 08-05dedecms(織夢)副欄目數(shù)量限制代碼修改
- 08-05DEDE織夢data目錄下的sessions文件夾有什


