Blend 2015 教程 (四)控件模板

前一篇講述了修改ListBox樣式的方法,本篇將修改性別顯示區域的樣式。程序員

1. 選擇ListBox控件,編輯ItemTemplate的當前項,選擇CheckBox控件,在美工板導航欄中點擊CheckBox,選擇 編輯模板-建立空白項,進入控件模板編輯模式。express

2. 選擇文檔大綱面板中的Grid,在屬性面板中把Width改成30。app

3. 在Grid中繪製一個TextBlock並重置佈局,將Text屬性改成男,HorizontalAlignment屬性爲居中對齊。框架

4. 在狀態面板中點擊Checked,以下圖所示。工具

Image(29)

在屬性面板中把Text屬性改成女,文檔大綱面板以下圖,TextBlock下面有帶五角星圖標的Text屬性,表示該屬性有動畫存在。佈局

Image(30)

美工板以下圖所示,紅框表示正在錄製動畫。學習

Image(31)

此時運行程序能夠看到效果,點擊男或女文字能夠進行切換。動畫

5. 在文檔大綱面板中選擇Grid,在狀態面板中選擇基本,而後把Grid的Background改成藍色。在狀態面板中選擇Checked,將背景色改成紅色。能夠看到Grid下加入了Background的動畫。spa

能夠運行程序試驗效果。設計

6. 在狀態面板中選擇基本,在文檔大綱面板中右鍵點擊Grid,選擇 分組-Grid。切換到資產面板,選擇控件分類,拖動一個Border到文檔大綱面板中的外層Grid中的內層Grid下方,以下圖。

Image(32)

再拖動一個Border到這個Border的下方,清除兩個Border的BorderBrush和BorderThickness屬性。上面的Border的Background屬性設爲黑色,下面的設爲白色,透明度(Opacity)都設置爲0。

7. 在狀態面板中點擊Pressed,在文檔大綱面板中選擇上面那個Border,把透明度設置爲10。在狀態面板中點擊MouseOver,在文檔大綱面板中選擇下面那個Border,把透明度設置爲30。

運行程序,查看效果,最終效果以下圖所示。

Image(33)

能夠調節窗口大小,看到咱們的程序是自適應的,以下圖。

Image(34)

最終的完整程序以下。

<Window
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:BlendDemo"
        xmlns:System="clr-namespace:System;assembly=mscorlib" x:Class="BlendDemo.MainWindow"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525" d:DataContext="{d:DesignData /SampleData/SampleDataSource/SampleDataSource.xaml}">
    <Window.Resources>
        <DataTemplate x:Key="PeopleListDataTemplate">
            <Grid Height="100" Width="200">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                </Grid.RowDefinitions>
                <Border Style="{DynamicResource SubtitleStyle}">
                    <Grid>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="*"/>
                            <ColumnDefinition Width="Auto"/>
                        </Grid.ColumnDefinitions>
                        <TextBlock Height="Auto" TextWrapping="NoWrap" Text="{Binding Name}" Width="Auto" Style="{DynamicResource CoreTextStyle}" TextTrimming="WordEllipsis" ToolTip="{Binding Name}"/>
                        <CheckBox Content="男" Grid.Column="1" Height="Auto" Width="Auto" IsChecked="{Binding Sex}" Style="{DynamicResource CheckBoxBaseStyle}" Template="{DynamicResource CheckBoxControlTemplate1}"/>
                    </Grid>
                </Border>
                <TextBlock Grid.Row="1" TextWrapping="Wrap" Text="{Binding Description}" Margin="5"/>
            </Grid>
        </DataTemplate>
        <Style x:Key="TitleStyle" TargetType="{x:Type Border}">
            <Setter Property="Padding" Value="10"/>
            <Setter Property="Background" Value="#FFDEDDDD"/>
        </Style>
        <ItemsPanelTemplate x:Key="PeopleListItemsPanelTemplate">
            <WrapPanel IsItemsHost="True"/>
        </ItemsPanelTemplate>
        <Style x:Key="SubtitleStyle" TargetType="{x:Type Border}">
            <Setter Property="Background" Value="#FFB2E8F3"/>
            <Setter Property="Padding" Value="5"/>
        </Style>
        <Style x:Key="FocusVisual">
            <Setter Property="Control.Template">
                <Setter.Value>
                    <ControlTemplate>
                        <Rectangle Margin="2" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
        <SolidColorBrush x:Key="Item.MouseOver.Background" Color="#1F26A0DA"/>
        <SolidColorBrush x:Key="Item.MouseOver.Border" Color="#a826A0Da"/>
        <SolidColorBrush x:Key="Item.SelectedInactive.Background" Color="#3DDADADA"/>
        <SolidColorBrush x:Key="Item.SelectedInactive.Border" Color="#FFDADADA"/>
        <SolidColorBrush x:Key="Item.SelectedActive.Background" Color="#3DEEE751"/>
        <SolidColorBrush x:Key="Item.SelectedActive.Border" Color="#FF26A0DA"/>
        <Style x:Key="PeopleListItemStyle" TargetType="{x:Type ListBoxItem}">
            <Setter Property="SnapsToDevicePixels" Value="True"/>
            <Setter Property="Padding" Value="0"/>
            <Setter Property="HorizontalContentAlignment" Value="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="VerticalContentAlignment" Value="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/>
            <Setter Property="Background" Value="Transparent"/>
            <Setter Property="BorderBrush" Value="#FF2391DE"/>
            <Setter Property="BorderThickness" Value="1"/>
            <Setter Property="FocusVisualStyle" Value="{StaticResource FocusVisual}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType ="{x:Type ListBoxItem}">
                        <Border x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}" SnapsToDevicePixels="true">
                            <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
                        </Border>
                        <ControlTemplate.Triggers>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="IsMouseOver" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.MouseOver.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.MouseOver.Border}"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="False"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedInactive.Border}"/>
                            </MultiTrigger>
                            <MultiTrigger>
                                <MultiTrigger.Conditions>
                                    <Condition Property="Selector.IsSelectionActive" Value="True"/>
                                    <Condition Property="IsSelected" Value="True"/>
                                </MultiTrigger.Conditions>
                                <Setter Property="Background" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Background}"/>
                                <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource Item.SelectedActive.Border}"/>
                            </MultiTrigger>
                            <Trigger Property="IsEnabled" Value="False">
                                <Setter Property="TextElement.Foreground" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="Margin" Value="5"/>
        </Style>
        <ControlTemplate x:Key="CheckBoxControlTemplate1" TargetType="{x:Type CheckBox}">
            <Grid Width="30">
                <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CommonStates">
                        <VisualStateGroup.Transitions>
                            <VisualTransition GeneratedDuration="0"/>
                        </VisualStateGroup.Transitions>
                        <VisualState x:Name="Normal"/>
                        <VisualState x:Name="MouseOver">
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border1">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="0.3"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Pressed">
                            <Storyboard>
                                <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="border">
                                    <EasingDoubleKeyFrame KeyTime="0" Value="0.1"/>
                                </DoubleAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Disabled"/>
                    </VisualStateGroup>
                    <VisualStateGroup x:Name="CheckStates">
                        <VisualState x:Name="Checked">
                            <Storyboard>
                                <StringAnimationUsingKeyFrames Storyboard.TargetProperty="(TextBlock.Text)" Storyboard.TargetName="textBlock">
                                    <DiscreteStringKeyFrame KeyTime="0" Value="女"/>
                                </StringAnimationUsingKeyFrames>
                                <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="grid">
                                    <EasingColorKeyFrame KeyTime="0" Value="#FFF59A91"/>
                                </ColorAnimationUsingKeyFrames>
                            </Storyboard>
                        </VisualState>
                        <VisualState x:Name="Unchecked"/>
                        <VisualState x:Name="Indeterminate"/>
                    </VisualStateGroup>
                </VisualStateManager.VisualStateGroups>
                <Grid x:Name="grid" Width="Auto" Background="#FF91BFF5">
                    <TextBlock x:Name="textBlock" TextWrapping="Wrap" Text="男" HorizontalAlignment="Center"/>
                </Grid>
                <Border x:Name="border" Background="Black" Opacity="0"/>
                <Border x:Name="border1" Background="White" Opacity="0"/>
            </Grid>
        </ControlTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition/>
        </Grid.RowDefinitions>
        <Border Style="{DynamicResource TitleStyle}" >
            <TextBlock Text="人員列表" Style="{DynamicResource TitleTextStyle}"/>
        </Border>
        <ListBox Grid.Row="1" ItemsSource="{Binding Persons}" ItemTemplate="{DynamicResource PeopleListDataTemplate}" HorizontalContentAlignment="Stretch" ItemsPanel="{DynamicResource PeopleListItemsPanelTemplate}" ScrollViewer.HorizontalScrollBarVisibility ="Disabled" ItemContainerStyle="{DynamicResource PeopleListItemStyle}"/>
    </Grid>
</Window>

正式項目中能夠把樣式移入單獨的文件中,並起好的名字,便於複用。

若是仔細觀察會發現,最終版本的性別顯示CheckBox和原先沒改過樣式以前的版本表達的邏輯是相反的,哪一種是對的取決於數據中如何定義Bool型Sex屬性的含義。這進一步說明了Binding的數據的屬性名,類型,語義是View層和ViewModel層的接口,須要仔細定義。若是這兩層是兩我的或兩個組開發,這一點就更爲重要了。

總結,本系列文章初步探究了在新版Blend 2015中進行可視化表現層開發的方法。新版Blend因爲使用Visual Studio框架,IDE的總體使用方法和Visual Studio保持了一致。項目文件引用等的管理使用和VS同樣的解決方案資源管理器,源代碼版本管理使用和VS同樣的團隊資源管理器,不只有源代碼管理,更有高級的團隊項目管理功能。美工板和其餘面板的使用方法和原來基本一致,但最重要的改進之處在於對XAML代碼的手動編寫能力和C#代碼的編寫能力達到了VS的水平。

Blend的核心是美工板,文檔大綱面板和屬性面板。因此文章中對這些部分的介紹較多,其餘面板的使用方法也都作了基本的介紹。文章中進行了一個完整的示例操做演示,經過學習和親手練習,並認真思考理解,能夠達到初步掌握Blend的基本使用方法的目的。

文章中的演示所有使用了可視化開發方法,沒有直接編寫一行代碼。這說明Blend的可視化開發能力是很強的,微軟XAML平臺的設計初衷,讓學美術出身的人直接作設計,而不用先出效果圖,再由程序員還原設計的目標是能夠實現的。儘管Blend的可視化開發能力很強,但有些時候直接修改XAML代碼能更快地完成工做。還有可視化開發不能完成任務,必須直接編寫XAML代碼的時候。若是有動態的效果,須要較複雜的邏輯的時候,可能還須要編寫C#代碼。這說明從事表現層開發的開發人員,是須要精通XAML語言,並初步掌握C#語言的。這也是微軟使用Visual Studio框架從新制做Blend,以加強代碼編寫能力的緣由。

總之,微軟的XAML技術是一個很好的技術,在WPF,Silverlight,Windows Store App,Windows Phone,以及最新的Universal Windows App等類型的應用開發平臺中都有使用。該平臺可以提供強大的靈活性(自適應佈局,數據模板,控件模板),出色的表現效果(動畫,VSM,觸發器)和優秀的項目結構(資源,Style,Binding,MVVM),是微軟的客戶端程序表現層開發的核心技術,值得認真學習和深刻研究。

Blend爲XAML平臺的可視化開發提供了工具支持。學習美術出身的人能夠首先學習並熟練掌握Blend可視化開發,而後學習XAML語言和其背後的機制原理,再逐步學習一些C#語言和麪向對象思想等程序設計方面的內容,通過不斷的努力,最後就能夠達到把本身的設計能力和水平在微軟的XAML平臺上進行完美展示的效果,這也是微軟想達到的目標和公司領導願意看到的結果。

相關文章
相關標籤/搜索