当前位置:网站首页 / WPF / 正文

[Aaronyang翻墙好文章WPF] TabControl改写

时间:2015年03月24日 | 作者 : aaronyang | 分类 : WPF | 浏览: 2636次 | 评论 0

怎样定义个WPF TabControl的样式

The WPF TabControl is control used to group the contents in tabular way. This is very usable when you as a UI designer would like to save more space in yourWindow while configuring more fields in the UI.

Try to look a little bit the normal TabControl of the WPF.
Image 9.png
You'll see the TabControl contains four headers that separate the contents based on the needs per group. In WPF, you call the items/headers as TabItem.

The TabItem object is the one who is being added as a child of the TabControland to be the container of the other controls inside TabControl. You'll see in the above image the TabItem(s) labeled GeneralActionsOptions andTools. So every control placed in General tab couldn't be seen in Actions tab as they were a separate group.
Let's go directly how could you customize or design your favorite TabControl.

Target TabControl and TabItem Design

There are no PARTS on the template of the TabControl, all you have to do is to customized it with the combinations of available controls from WPF. You should also create for your own Style for TabItem (same as TabControl it is a composite control and don't have any PART on its template).

Our target design for TabControl is below:
Image 8.png
First you  should create a Style for TabItem as it is required when you are applying a template for TabControl. With the image above, it has three style existed for TabItem (styleTabItemLeftstyleTabItemDefault andstyleTabItemRight). Each of them has different style and border.

Style for left TabItem

For the left style of the above's TabItem, we need to create a left rounded style and a little gradient background and soft text. Below is the XAML for this one.

<Style x:Key="styleTabItemLeft" TargetType="{x:Type TabItem}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Border x:Name="rightBorder"
                        Background="{StaticResource ResourceKey=gradientBrushSegmentedTabItem}"
                        BorderThickness="0,0,1,0"
                        BorderBrush="#032A6B"
                        CornerRadius="4,0,0,4">
                    <Border x:Name="leftBorder"
                            BorderThickness="1,0,0,0"
                            BorderBrush="#2172B1"
                            CornerRadius="4,0,0,4">
                        <ContentPresenter x:Name="ContentSite"
                                            ContentSource="Header"
                                            Grid.Row="1"
                                            HorizontalAlignment="Stretch"
                                            Margin="20,4,20,5"
                                            RecognizesAccessKey="True"
                                            VerticalAlignment="Center"
                                            TextBlock.FontSize="14"
                                            TextBlock.Foreground="#FFFFFF">
                            <ContentPresenter.Effect>
                                <DropShadowEffect BlurRadius="0.0"
                                                  Color="#032A6B"
                                                  Direction="90"
                                                  Opacity="1"
                                                  ShadowDepth="1" />
                            </ContentPresenter.Effect>
                        </ContentPresenter>
                    </Border>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="rightBorder"
                                Property="Background"
                                Value="{StaticResource ResourceKey=gradientBrushSegmentedActiveTabItem}" />
                        <Setter TargetName="leftBorder"
                                Property="BorderThickness"
                                Value="0" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Style for right TabItem

The same with left TabItem, but only we adjusted the rounded corner to the right. The XAML below address it.

<Style x:Key="styleTabItemRight" TargetType="{x:Type TabItem}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Border x:Name="rightBorder"
                        Background="{StaticResource ResourceKey=gradientBrushSegmentedTabItem}"
                        BorderThickness="0,0,1,0"
                        BorderBrush="#032A6B"
                        CornerRadius="0,4,4,0">
                    <Border x:Name="leftBorder"
                            BorderThickness="1,0,0,0"
                            BorderBrush="#2172B1"
                            CornerRadius="0,4,4,0">
                        <ContentPresenter x:Name="ContentSite"
                                            ContentSource="Header"
                                            Grid.Row="1"
                                            HorizontalAlignment="Stretch"
                                            Margin="20,4,20,5"
                                            RecognizesAccessKey="True"
                                            VerticalAlignment="Center"
                                            TextBlock.FontSize="14"
                                            TextBlock.Foreground="#FFFFFF">
                            <ContentPresenter.Effect>
                                <DropShadowEffect BlurRadius="0.0"
                                                    Color="#032A6B"
                                                    Direction="90"
                                                    Opacity="1"
                                                    ShadowDepth="1" />
                            </ContentPresenter.Effect>
                        </ContentPresenter>
                    </Border>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="rightBorder"
                                Property="Background"
                                Value="{StaticResource ResourceKey=gradientBrushSegmentedActiveTabItem}" />
                        <Setter TargetName="leftBorder"
                                Property="BorderThickness"
                                Value="0" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Style for default TabItem

This time this is not rounded and you'll notice an inset/outset if defaulted. The XAML below address it.

<Style x:Key="styleTabItemDefault" TargetType="{x:Type TabItem}">
    <Setter Property="FocusVisualStyle" Value="{x:Null}"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabItem}">
                <Border x:Name="rightBorder"
                        Background="{StaticResource ResourceKey=gradientBrushSegmentedTabItem}"
                        BorderThickness="0,0,1,0"
                        BorderBrush="#032A6B">
                    <Border x:Name="leftBorder"
                            BorderThickness="1,0,0,0"
                            BorderBrush="#2172B1">
                        <ContentPresenter x:Name="ContentSite"
                                            ContentSource="Header"
                                            Grid.Row="1"
                                            HorizontalAlignment="Stretch"
                                            Margin="20,4,20,5"
                                            RecognizesAccessKey="True"
                                            VerticalAlignment="Center"
                                            TextBlock.FontSize="14"
                                            TextBlock.Foreground="#FFFFFF">
                            <ContentPresenter.Effect>
                                <DropShadowEffect BlurRadius="0.0"
                                                    Color="#032A6B"
                                                    Direction="90"
                                                    Opacity="1"
                                                    ShadowDepth="1" />
                            </ContentPresenter.Effect>
                        </ContentPresenter>
                    </Border>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsSelected" Value="True">
                        <Setter TargetName="rightBorder"
                                Property="Background"
                                Value="{StaticResource ResourceKey=gradientBrushSegmentedActiveTabItem}" />
                        <Setter TargetName="leftBorder"
                                Property="BorderThickness"
                                Value="0" />
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

You will notice that the three styles almost the same in foundation but only the design for the rounded corners are different. You will also notice that some variables like gradientBrushSegmentedActiveTabItem,gradientBrushSegmentedTabItem were referenced. This is actually my resource object implemented to make the background of the TabItem header looks very nice. The XAML below is the code for this.

<LinearGradientBrush x:Key="gradientBrushTabControlHeader" StartPoint="0,0.5" EndPoint="1,0.5">
    <GradientStop Color="#002E8A" Offset="0" />
    <GradientStop Color="#0071B7" Offset="0.5" />
    <GradientStop Color="#002E8A" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="gradientBrushSegmentedTabItem" StartPoint="0.5,0" EndPoint="0.5,1">
    <GradientStop Color="#4C8BC0" Offset="0" />
    <GradientStop Color="#015CA3" Offset="0.49" />
    <GradientStop Color="#024795" Offset="0.50" />
    <GradientStop Color="#2C5198" Offset="1" />
</LinearGradientBrush>
<LinearGradientBrush x:Key="gradientBrushSegmentedActiveTabItem" StartPoint="0.5,0" EndPoint="0.5,1">
    <GradientStop Color="#000098" Offset="0" />
    <GradientStop Color="#000075" Offset="0.33" />
    <GradientStop Color="#000075" Offset="0.66" />
    <GradientStop Color="#000082" Offset="1" />
</LinearGradientBrush>

Once you have already completed all the Style for the TabItem, next you should do your own Style for the TabControl applying the above styles you created.

Styling the TabControl

The WPF TabControl is a composite control and there is no PART on its template. This mean that you can do design anything you like to place on this template. But two thing you need not to  forget is placing down theContentPresenter and StackPanel (setting the IsItemsHost = True) inside of its template. The ContentPresenter object will be the one be used by WPF to be the container of the content and the StackPanel will be the one to host the TabItem.

See the XAML below:

<Style x:Key="styleTabControl" TargetType="{x:Type TabControl}">
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TabControl}">
                <Grid KeyboardNavigation.TabNavigation="Local" ShowGridLines="False">
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="*"/>
                    </Grid.RowDefinitions>
                    <Grid Name="Header"
                            Background="{StaticResource ResourceKey=gradientBrushTabControlHeader}"
                            Grid.Column="0"
                            Grid.Row="0">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                            <ColumnDefinition Width="Auto"></ColumnDefinition>
                            <ColumnDefinition Width="*"></ColumnDefinition>
                        </Grid.ColumnDefinitions>
                        <Border Background="#032A6B"
                                BorderBrush="#032A6B"
                                BorderThickness="1,1,0,1"
                                CornerRadius="4"
                                Grid.Column="1"
                                Grid.Row="0"
                                KeyboardNavigation.TabIndex="1"
                                Margin="6"
                                Panel.ZIndex="1">
                            <StackPanel Name="HeaderPanel"
                                        IsItemsHost="True"
                                        Orientation="Horizontal">
                            </StackPanel>
                            <Border.BitmapEffect>
                                <DropShadowBitmapEffect Color="#0047CC"
                                                        Direction="180"
                                                        ShadowDepth="1"
                                                        Opacity="1"
                                                        Softness="1">
                                </DropShadowBitmapEffect>
                            </Border.BitmapEffect>
                        </Border>
                    </Grid>
                    <ContentPresenter Grid.Row="1" ContentSource="SelectedContent" Margin="5"
                                        KeyboardNavigation.DirectionalNavigation="Contained"
                                        KeyboardNavigation.TabIndex="2"
                                        KeyboardNavigation.TabNavigation="Local" />
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

Above's XAML address the design of our target TabControl design. It creates a background for  its header and some drop shadow below it.

Applying the styles in the TabControl

All you have to do is to create a one ResourceDictionary file and place it inside your solution. Set the Build Action to Resource and add it as a resource of your Window (or the parent container of your TabControl).

Once you are done, apply each style in your control and its children (TabItems). Below XAML is the sample (placing TabControl inside the Window element).

<Window x:Class="CodesDirectory.WIN_TabControl"
        xmlns="/winfx/2006/xaml/presentation"
        xmlns:x="/winfx/2006/xaml"
        Title="WPF TabControl" Height="300" Width="300">
    <Window.Resources>
        <ResourceDictionary Source="/Styles/TabControl.xaml"></ResourceDictionary>
    </Window.Resources>
    <Grid>
        <TabControl Margin="5" Style="{DynamicResource ResourceKey=styleTabControl}">
            <TabItem Header="General" Style="{DynamicResource ResourceKey=styleTabItemLeft}">
                <TextBlock>The content for General tab.</TextBlock>
            </TabItem>
            <TabItem Header="Actions" Style="{DynamicResource ResourceKey=styleTabItemDefault}">
                <TextBlock>The content for Action tab.</TextBlock>
            </TabItem>
            <TabItem Header="Options" Style="{DynamicResource ResourceKey=styleTabItemDefault}">
                <TextBlock>The content for Options tab.</TextBlock>
            </TabItem>
            <TabItem Header="Tools" Style="{DynamicResource ResourceKey=styleTabItemRight}">
                <TextBlock>The content for Tools tab.</TextBlock>
            </TabItem>
        </TabControl>
    </Grid>
</Window>


推荐您阅读更多有关于“WPF国外文章,”的文章

猜你喜欢

额 本文暂时没人评论 来添加一个吧

发表评论

必填

选填

选填

必填

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

  查看权限

合肥科大智能常年招聘.NET,Web前端,有想换工作的私聊我AY唯一QQ:875556003和AY交流

抖音号:wpfui,可以看到我的很多作品效果,私活合作请qq联系我

AYUI8社区版Github地址:前往获取

作者:杨洋(AaronYang简称AY,安徽六安人)目前是个人,还没公司AY唯一QQ:875556003和AY交流

高中学历,2015年1月17日开始,兴趣学习研究WPF,目前工作繁忙,不接任何活

声明:AYUI7个人与商用免费,源码可购买。部分DEMO不免费.AY主要靠卖技术服务挣钱

不是从我处购买的ayui7源码,我不提供任何技术服务,如果你举报从哪里买的,我可以帮你转正为我的客户,并送demo

查看捐赠

AYUI7.X MVC教程 更新如下:

第一课 第二课 程序加密教程

vs2015 企业版密钥HM6NR-QXX7C-DFW2Y-8B82K-WTYJV

vs2017 企业版密钥NJVYC-BMHX2-G77MM-4XJMR-6Q8QF

标签列表