为建立中文知识库加块砖 ——中科大胡不归
问题描述
WPF可以轻松通过Style实现自定义的控件样式,比如如下这种带高亮条选中效果的TabItem。
代码实例
1. Style定义
在App.xaml中定义TabItem的图片按钮样式。此处定义:TabItem在Normal态下显示Icon属性传入的图片资源,在选中时显示IconSelected传入的图片资源。【可选】在选中时修改TabItem的背景。
<Application.Resources>
<Style TargetType="{x:Type local:MyTabItem}">
<Setter Property="Foreground" Value="Black" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyTabItem}">
<!-- 常态显示Icon -->
<Grid x:Name="Panel">
<Image x:Name="img2Off" Width="20" Height="20" Source="{TemplateBinding Icon}" Margin="5" />
</Grid>
<ControlTemplate.Triggers>
<!-- 选中时 -->
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Panel" Property="Background" Value="LightSkyBlue" />
<Setter TargetName="img2Off" Property="Source" Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IconSelected}" />
</Trigger>
<!-- 非选中时 -->
<Trigger Property="IsSelected" Value="False">
<Setter TargetName="Panel" Property="Background" Value="White" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Application.Resources>
需要注意的是TemplateBinding只能用在ControlTemplate中,Setter中是没有此功能。Setter需要使用布局中传入的IconSelected属性,可以通过如下形式:Value="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IconSelected}"
。
2. 自定义MyTabItem
因为需要用到xaml中传入的新的属性参数,所以我们需要继承TabItem实现自定义MyTabItem类。
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
namespace WpfApplication2
{
public class MyTabItem : TabItem
{
static MyTabItem()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(MyTabItem), new FrameworkPropertyMetadata(typeof(MyTabItem)));
}
// 定义Icon属性
public ImageSource Icon
{
get => (ImageSource) GetValue(IconProperty);
set => SetValue(IconProperty, value);
}
public static readonly DependencyProperty IconProperty =
DependencyProperty.Register("Icon", typeof(ImageSource), typeof(MyTabItem), new PropertyMetadata(null));
// 定义IconSelected属性
public ImageSource IconSelected
{
get => (ImageSource) GetValue(IconSelectedProperty);
set => SetValue(IconSelectedProperty, value);
}
public static readonly DependencyProperty IconSelectedProperty =
DependencyProperty.Register("IconSelected", typeof(ImageSource), typeof(MyTabItem), new PropertyMetadata(null));
}
}
3. 控件引用
<Window x:Class="WpfApplication2.TabDemo"
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"
xmlns:local="clr-namespace:WpfApplication2"
mc:Ignorable="d"
Title="TabDemo" Height="450" Width="800">
<Grid>
<TabControl TabStripPlacement="Right" Height="{Binding ElementName=ParentPanel, Path=Height}"
Width="{Binding ElementName=ParentPanel, Path=Width}" >
<local:MyTabItem x:Name="TabItem1" Icon="Resource/Image/studio.ico" IconSelected="Resource/Image/studio3.ico">
<TextBlock>江山各有</TextBlock>
</local:MyTabItem>
<local:MyTabItem x:Name="TabItem2" Icon="Resource/Image/studio.ico" IconSelected="Resource/Image/studio3.ico">
<TextBlock>风景无限</TextBlock>
</local:MyTabItem>
</TabControl>
</Grid>
</Window>