這是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 & Send"> <TextBlock>Save & 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 翻譯,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者博客鏈接,謝謝!