[原譯]模擬Office2010文件菜單的TabControl模板


 

 

這是Office2010中的文件菜單點開后的效果。本文我將以強大的WPF來實現類似的效果。希望你能有所收獲。而不是只拷貝/粘貼代碼而已。

 開始之前。先把TabControl找個地方放着。

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

    <TabControl Name="tabSteps">

        <TabItem Header="Info" IsSelected="True">

            <TextBlock>Info content</TextBlock>

        </TabItem>

        <TabItem Header="Recent">

            <TextBlock>Recent content tab</TextBlock>

        </TabItem>

        <TabItem Header="New">

            <TextBlock>New content tab</TextBlock>

        </TabItem>

        <TabItem Header="Print">

            <TextBlock>Print content tab</TextBlock>

        </TabItem>

        <TabItem Header="Save &amp; Send">

            <TextBlock>Save &amp; send content tab</TextBlock>

        </TabItem>

        <TabItem Header="Help">

            <TextBlock>Help tab</TextBlock>

        </TabItem>

    </TabControl>

</Window>

 

然后會大概是這個效果

 

為了改變TabControl的顯示效果。我們使用模板機制,我們把模板寫進一個資源字典里。這樣就可以重用了。添加一個資源字典的步驟如下

右鍵點擊工程-添加-資源字典

然后在資源字典里添加一些代碼。

    

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

        <Grid>

            <Grid.ColumnDefinitions>

                <ColumnDefinition Width="160" />

                <ColumnDefinition/>

            </Grid.ColumnDefinitions>

            <Border Background="#FFE9ECEF"

                    Grid.Column="0"

                    BorderBrush="LightGray"

                    BorderThickness="1"

                    SnapsToDevicePixels="True" />

            <StackPanel IsItemsHost="True"

                        Grid.Column="0"

                        Margin="0,0,-1,0"

                        SnapsToDevicePixels="True" />

            <ContentPresenter

                Content="{TemplateBinding SelectedContent}"

                Grid.Column="1"

                Margin="15,0,0,0" />

        </Grid>

    </ControlTemplate>

 

這樣就添加了一個有一個grid元素的名為OfficeTabControl的控件模板 . Grid 被分成兩列,一列是標簽頁,一列是頁內容。左邊的列包含一個灰色背景和亮灰色的邊緣線,然后一個StackPanel,IsItemsHost屬性被設置為true,

這樣標簽項被會放在這個棧面板里。第二列是ContentPresenter 這會放置標簽頁內容。然后讓我們前面的TabControl使用新模板。設置Template 屬性。

   

 <Window.Resources>

        <ResourceDictionary>

            <ResourceDictionary.MergedDictionaries>

                <ResourceDictionary Source="OfficeTab.xaml" />

            </ResourceDictionary.MergedDictionaries>

        </ResourceDictionary>

    </Window.Resources>

    <TabControl Name="tabSteps" Template="{StaticResource OfficeTabControl}">

 

在這之前,先把資源字典加到窗體的Reesouce里。然后再設置。然后運行軟件。效果會有一些不一樣。

 

然后要修改左側單個標簽的顯示效果。通過改變模板來實現。給模板添加如下的代碼

 

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

    <ControlTemplate.Resources>

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

            <Setter Property="Template">

                <Setter.Value>

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

                        <Grid SnapsToDevicePixels="True">

                            <ContentPresenter

                                Name="buttonText"

                                Margin="15,0,5,0"

                                TextBlock.FontFamily="Calibri"

                                TextBlock.FontSize="12pt"

                                TextBlock.Foreground="Black"

                                Content="{TemplateBinding Header}"

                                VerticalAlignment="Center"/>

                        </Grid>

                    </ControlTemplate>

                </Setter.Value>

            </Setter>

        </Style>

    </ControlTemplate.Resources>

 

然后再運行

 

VisualState很有意思。我們可以放在Grid里。然后設置正常狀態和鼠標懸停的狀態。

為了添加鼠標懸停效果,我們添加兩個Borders元素。一個右邊緣是灰線,另一個用在背景上。亮藍色放在上下邊緣

<Border Name="hoverShape"

        Height="40"

        Margin="0,0,1,0"

        SnapsToDevicePixels="True"

        BorderThickness="0,0,1,0"

        BorderBrush="LightGray">

    <Border BorderBrush="#FFA1B7EA"

            BorderThickness="0,1"

            Background="#FFE5EEF9"

            Height="40"

            SnapsToDevicePixels="True" />

</Border>

 

之后,我們為VisualState創建故事板,一個是正常狀態。會使得hoverShape的透明度為0.另一個是鼠標懸停的狀態。透明度會變成1

<Grid SnapsToDevicePixels="True">

    <VisualStateManager.VisualStateGroups>

        <VisualStateGroup Name="CommonStates">

            <VisualState Name="MouseOver">

                <Storyboard>

                    <DoubleAnimation

                        Storyboard.TargetName="hoverShape"

                        Storyboard.TargetProperty="Opacity"

                        To="1"

                        Duration="0:0:.1"/>

                </Storyboard>

            </VisualState>

            <VisualState Name="Normal">

                <Storyboard>

                    <DoubleAnimation

                        Storyboard.TargetName="hoverShape"

                        Storyboard.TargetProperty="Opacity"

                        To="0"

                        Duration="0:0:.1"/>

                </Storyboard>

            </VisualState>

        </VisualStateGroup>

 

之后效果如下

 

然后添加選中項的樣式,在hoverShape 下面再添加一個Border,名字是buttonShape。通過這個我們給被選中項的上下邊緣添加2個像素的黑藍色邊緣,

在 Expression Blend中打開, 使用鋼筆工具繪制個你想要的路徑形狀即可。然后把生成的xaml代碼拷些過來。

 

也可以直接用我的代碼。。不顧我說過要怎么做了。

最終看起來應該是這樣的。

<Border

    Name="buttonShape"

    Opacity="0"

    BorderBrush="#FF0343A6"

    BorderThickness="0,2"

    Height="40"

    SnapsToDevicePixels="True">

    <Path

        Data="M214,108 L346,108 346.125,118.125 337.75,126.125

                   346.375,134 346.375,143.875 214.25,144.25 z"

        SnapsToDevicePixels="True"

        Stretch="Fill"

        Height="40">

        <Path.Fill>

            <RadialGradientBrush GradientOrigin="0.2,0.5" RadiusX="0.8" RadiusY="0.8">

                <GradientStop Color="#FF5FA3F6" Offset="0" />

                <GradientStop Color="#FF0C55B9" Offset="1" />

            </RadialGradientBrush>

        </Path.Fill>

    </Path>

</Border>

 

當你運行的時候你會發現沒什么變化。我們還要定義被選中標簽的VisualState

當添加如下代碼的時候 添加一個VisualState組。也就是 SelectionStates ,然后給選中/為選中的狀態添加行為/故事板。.這里通過修改透明度來實現一些效果

<VisualStateGroup Name="SelectionStates">

    <VisualState Name="Selected">

        <Storyboard>

            <DoubleAnimation

                Storyboard.TargetName="buttonShape" Storyboard.TargetProperty="Opacity"

                To="1" Duration="0:0:.3"/>

            <DoubleAnimation

                Storyboard.TargetName="hoverShape" Storyboard.TargetProperty="Opacity"

                To="0" Duration="0:0:.1"/>

            <ColorAnimation

                Storyboard.TargetName="buttonText"

                Storyboard.TargetProperty=

                            "(TextBlock.Foreground).(SolidColorBrush.Color)"

                To="White" Duration="0:0:.1" />

        </Storyboard>

    </VisualState>

    <VisualState Name="Unselected">

        <Storyboard>

            <DoubleAnimation

                Storyboard.TargetName="buttonShape"

                Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:.1"/>

            <DoubleAnimation

                Storyboard.TargetName="hoverShape"

                Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:.1"/>

        </Storyboard>

    </VisualState>

</VisualStateGroup>

 

現在再運行會發現效果更好了

 

 

還有個小問題,就是那個陷進入的小三角形的背景顏色依然還在。通過在下面添加一個白色的形狀。,並且對故事板的選中和為選中狀態改變一下透明度就可以了。

<VisualStateGroup Name="SelectionStates">

    <VisualState Name="Selected">

        <Storyboard>

            <DoubleAnimation

                Storyboard.TargetName="buttonBackgroundShape"

                Storyboard.TargetProperty="Opacity" To="1" Duration="0"/>

        </Storyboard>

    </VisualState>

    <VisualState Name="Unselected">

        <Storyboard>

            <DoubleAnimation

                Storyboard.TargetName="buttonBackgroundShape"

                Storyboard.TargetProperty="Opacity" To="0" Duration="0"/>

        </Storyboard>

    </VisualState>

</VisualStateGroup>

 

最終效果如下:

 

 

源代碼地址: OfficeTab.xaml (8.37 KB).

許可

本文包括源代碼和文件在CPOL下授權

原文地址:Building-a-control-template-style-for-the-tabContr

 著作權聲明:本文由http://leaver.me 翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者博客鏈接,謝謝!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM