WPF中的Tab控件 – 从里到外

来源:互联网 发布:linux系统时间同步 编辑:程序博客网 时间:2024/05/16 18:19

原文地址:http://www.dingos.cn/index.php?topic=2014.0

 

WinForm中的Tab控件,有许多不足的地方。如果你想对样式或功能做出改变,最好从头开始自己编写Tab控件。WPF中的Tab控件向正确的方向迈了一大步,因为WPF的强大的样式和控件模板,你几乎可以完全控制Tab控件的外观。这篇文章将介绍Tab控件并演示如何按你想的更新皮肤。

现在让我们从简单的示例开始 在窗体中放置一个非常标准的Tab控件,并添加一组Tab

<Window x:Class="TabControlTutorial.Window1"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Title="WPF Tabs" Height="281" Width="454">

    <Grid>

        <TabControl>

            <TabItem Header="Cheese">

                The Cheese Tab

            </TabItem>

            <TabItem Header="Pepperoni">

                The Pepperoni Tab

            </TabItem>

            <TabItem Header="Mushrooms">

                The Mushrooms Tab

            </TabItem>

        </TabControl>

    </Grid>

</Window>

上面的代码给出一个非常标准的Tab控件外观,如下图所示。

WPF中的Tab控件 – 从里到外 - 夜晚回家 - 夜晚回家

像其他WPF控件一样,TabItem中可以包含其他任何WPF控件。

<Window x:Class="TabControlTutorial.Window1"

   xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

   xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

   Title="WPF Tabs" Height="281" Width="454">

    <Grid>

        <TabControl>

            <TabItem Header="Cheese">

                The Cheese Tab

            </TabItem>

            <TabItem Header="Pepperoni">

                <Image Source="pepperoni.jpg" />

            </TabItem>

            <TabItem Header="Mushrooms">

                The Mushrooms Tab

            </TabItem>

        </TabControl>

    </Grid>

</Window>

上面的代码,如下显示:

WPF中的Tab控件 – 从里到外 - 夜晚回家 - 夜晚回家

这是简单的图像填充。如果你要的是每个Tab控件的每个Tab有自己的内容,上面的代码就可以了。让我们看一些更有趣的东西吧。就像TabItem中的内容一样,TabItemHeader属性也能包含其他的WPF控件。让我们在每个Tab中放置图片。

<Window x:Class="TabControlTutorial.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">

    <Grid>

        <TabControl>

            <TabItem>

                <TabItem.Header>

                    <StackPanel Orientation="Horizontal">

                        <Image Height="18" Source="cheese.jpg" />

                        <TextBlock Text="Cheese" Margin="2,0,0,0"

                                VerticalAlignment="Center" />

                    </StackPanel>

                </TabItem.Header>

            </TabItem>

            <TabItem>

                <TabItem.Header>

                    <StackPanel Orientation="Horizontal">

                        <Image Height="18" Source="pepperoni.jpg" />

                        <TextBlock Text="Pepperoni" Margin="2,0,0,0"

                                VerticalAlignment="Center" />

                    </StackPanel>

                </TabItem.Header>

            </TabItem>

            <TabItem>

                <TabItem.Header>

                    <StackPanel Orientation="Horizontal">

                        <Image Height="18" Source="mushrooms.jpg" />

                        <TextBlock Text="Mushrooms" Margin="2,0,0,0"

                                VerticalAlignment="Center" />

                    </StackPanel>

                </TabItem.Header>

            </TabItem>

        </TabControl>

    </Grid>

</Window>

做了上述操作后,如下图显示:

WPF中的Tab控件 – 从里到外 - 夜晚回家 - 夜晚回家

<!-- /* Font Definitions */ @font-face{font-family:宋体;panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-alt:SimSun;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 680460288 22 0 262145 0;}@font-face{font-family:"Cambria Math";panose-1:2 4 5 3 5 4 6 3 2 4;mso-font-charset:1;mso-generic-font-family:roman;mso-font-format:other;mso-font-pitch:variable;mso-font-signature:0 0 0 0 0 0;}@font-face{font-family:华文中宋;panose-1:2 1 6 0 4 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:647 135200768 16 0 262303 0;}@font-face{font-family:"/@华文中宋";panose-1:2 1 6 0 4 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:647 135200768 16 0 262303 0;}@font-face{font-family:"/@宋体";panose-1:2 1 6 0 3 1 1 1 1 1;mso-font-charset:134;mso-generic-font-family:auto;mso-font-pitch:variable;mso-font-signature:3 680460288 22 0 262145 0;} /* Style Definitions */ p.MsoNormal, li.MsoNormal, div.MsoNormal{mso-style-unhide:no;mso-style-qformat:yes;mso-style-parent:"";margin:0cm;margin-bottom:.0001pt;mso-para-margin-top:.5gd;mso-para-margin-right:0cm;mso-para-margin-bottom:0cm;mso-para-margin-left:0cm;mso-para-margin-bottom:.0001pt;text-align:justify;text-justify:inter-ideograph;mso-pagination:none;font-size:10.5pt;mso-bidi-font-size:15.0pt;font-family:"Courier New";mso-fareast-font-family:华文中宋;mso-bidi-font-family:宋体;color:black;mso-font-kerning:18.0pt;mso-bidi-font-weight:bold;}a:link, span.MsoHyperlink{mso-style-priority:99;color:blue;text-decoration:underline;text-underline:single;}a:visited, span.MsoHyperlinkFollowed{mso-style-noshow:yes;mso-style-priority:99;color:purple;mso-themecolor:followedhyperlink;text-decoration:underline;text-underline:single;}.MsoChpDefault{mso-style-type:export-only;mso-default-props:yes;mso-bidi-font-size:15.0pt;mso-ascii-font-family:"Courier New";mso-fareast-font-family:华文中宋;mso-hansi-font-family:"Courier New";mso-bidi-font-family:宋体;color:black;mso-font-kerning:18.0pt;mso-bidi-font-weight:bold;}.MsoPapDefault{mso-style-type:export-only;margin-top:0cm;mso-para-margin-top:.5gd;text-align:justify;text-justify:inter-ideograph;} /* Page Definitions */ @page{mso-page-border-surround-header:no;mso-page-border-surround-footer:no;}@page Section1{size:612.0pt 792.0pt;margin:72.0pt 90.0pt 72.0pt 90.0pt;mso-header-margin:36.0pt;mso-footer-margin:36.0pt;mso-paper-source:0;}div.Section1{page:Section1;}-->

有了上述的技术,你几乎可以使用Tab控件做任何事情。你所不能做的是,改变下划线选项卡的外观。幸运的是,WPF的样式系统简化了Tab控件的外观控制。默认情况下,选项卡的颜色依赖于运行在机器上的Windows主题。我们先修改标签的颜色和形状。

我们首先要做的是为TabItem控件定义我们需要的样式。WPF的样式和Web页面中的CSS是类似的,但功能更强大。

<Window x:Class="TabControlTutorial.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">

    <Window.Resources>

        <Style TargetType="{x:Type TabItem}">

            <Setter Property="Template">

                <Setter.Value>

                   <ControlTemplateTargetType="{x:Type TabItem}">

                       <Grid>

                            <Border Name="Border" Background="LightBlue"

                                     BorderBrush="Black" BorderThickness="1,1,1,1"

                                     CornerRadius="6,6,0,0" >

                                <ContentPresenter x:Name="ContentSite"

                                       VerticalAlignment="Center"

                                       HorizontalAlignment="Center"

                                       ContentSource="Header" Margin="12,2,12,2"/>

                            </Border>

                       </Grid>

                   </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

    </Window.Resources>

    <Grid>

        <TabControl>

            <TabItem Header="Cheese" />

            <TabItem Header="Pepperoni" />

            <TabItem Header="Mushrooms" />

        </TabControl>

    </Grid>

</Window>

样式定义在控件的资源中 这个例子Window包含了Tab控件。这里有一些说明,大部分是摘自MSDNhttp://msdn2.microsoft.com/en-us/library/ms752032.aspx)。让我们逐个标记来说明。

<Style TargetType="{x:Type TabItem}">

我们在这里为特殊类型的控件定义了样式 – TabItem。在Window中的任何TabItem都使用这个样式显示。

<Setter Property="Template">

    <Setter.Value>

        <ControlTemplate TargetType="{x:Type TabItem}">

这个样式简单的设置了TabItemTemplate属性。WPF控件大多数类型都包含Template,你可以让它看起来像你想要的东西。

<Grid>

    <Border Name="Border" Background="LightBlue" BorderBrush="Black"

            BorderThickness="1,1,1,1" CornerRadius="6,6,0,0" >

        <ContentPresenter x:Name="ContentSite" VerticalAlignment="Center"

                HorizontalAlignment="Center" ContentSource="Header"

                Margin="12,2,12,2"/>

    </Border>

</Grid>

在这个模板中,我们简单的放置了一个网格并给Tab一个边框及设置了背景色和一些圆角。这个ContentPresenter显示在我们的TabItem 在这个例子中你可以放置任何导向在头部。对Tab控件应用了这个样式,我们应用程序看上去如下图所示:

WPF中的Tab控件 – 从里到外 - 夜晚回家 - 夜晚回家

你可能注意到没有选中的Tab和选中的Tab没有什么不同,这也不是太糟糕的。这是因为当你重写TabItem的样式,将会对所有的都有影响。使用触发器实现就比较简单了。

<Style TargetType="{x:Type TabItem}">

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="{x:Type TabItem}">

                <Grid>

                    <Border Name="Border" Background="LightBlue"

                            BorderBrush="Black" BorderThickness="1,1,1,1"

                            CornerRadius="6,6,0,0" >

                        <ContentPresenter x:Name="ContentSite"

                                VerticalAlignment="Center"

                                HorizontalAlignment="Center"

                                ContentSource="Header" Margin="12,2,12,2"/>

                    </Border>

                </Grid>

                <ControlTemplate.Triggers>

                    <Trigger Property="IsSelected" Value="True">

                        <Setter TargetName="Border" Property="Background"

                            Value="LightBlue" />

                    </Trigger>

                    <Trigger Property="IsSelected" Value="False">

                        <Setter TargetName="Border" Property="Background"

                            Value="LightGray" />

                    </Trigger>

                </ControlTemplate.Triggers>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

TabItem被点击是,它的IsSelected属性被设置为true。因此,我们必须添加触发器观察IsSelected属性。当这个属性变为true,背景色设置为浅蓝色。当它为false是,背景色设置为浅灰色。现在运行后结果如下图所示:

WPF中的Tab控件 – 从里到外 - 夜晚回家 - 夜晚回家

我认为我们可以比较好的控制Tab控件了。现在我想改变Tab内容的背景色和边框。这和Tab的样式定义非常相似,只是我们都要TabItem的样式。

<Style  TargetType="{x:Type TabControl}">

    <Setter Property="Template">

        <Setter.Value>

            <ControlTemplate TargetType="{x:Type TabControl}">

                <Grid>

                    <Grid.RowDefinitions>

                        <RowDefinition Height="Auto"/>

                        <RowDefinition Height="*"/>

                    </Grid.RowDefinitions>

                    <TabPanel Grid.Row="0" Panel.ZIndex="1" Margin="0,0,4,-1"

                            IsItemsHost="True" Background="Transparent" />

                    <Border Grid.Row="1" BorderBrush="Black" BorderThickness="1"

                            CornerRadius="0, 12, 12, 12" >

                        <Border.Background>

                            <LinearGradientBrush>

                                <GradientStop Color="LightBlue" Offset="0" />

                                <GradientStop Color="White" Offset="1" />

                            </LinearGradientBrush>

                        </Border.Background>

                        <ContentPresenter ContentSource="SelectedContent" />

                    </Border>

                </Grid>

            </ControlTemplate>

        </Setter.Value>

    </Setter>

</Style>

使用这个代码后现在Tab表情看起来如下所示:

WPF中的Tab控件 – 从里到外 - 夜晚回家 - 夜晚回家

在这片文中中学习了如何创建和填充一个基本的Tab控件,还有更多设置TabTab内容的样式的先进技术。我认为这是WPF样式学习曲线的一小步,但你一点了解了它,你可以看到它是如此的强大。最棒的是,在这里我定义我的Tab控件的皮肤没有写任何C#代码。