UWP的UI主要由佈局容器和內容控件(ContentControl)組成。佈局容器是指Grid、StackPanel等繼承自Panel,可以擁有多個子元素的類。與此相對,ContentControl則只能包含單個子元素。
在UWP中,Button、CheckBox、ScrollViewer、Frame、ToolTip等都繼承自ContentControl,其它控件則不是在ContentTemplate中使用ContentControl,就是被ContentControl使用,可以說ContentControl是UWP中最重要的控件。
ContentControl的定義並不複雜,它主要包含這四個屬性:Content,ContentTemplate,ContentTemplateSelector,ContentTransitions。
1. Content
Content支持任何類型,它的值即ContentControl要顯示的對象。可以將Content的類型大致分爲兩大類:
未繼承自UIElement的類型: ContentControl調用這些類的ToString()方法獲取文本然後顯示。
繼承自UIElement的類型: ContentControl直接將它顯示在UI上。
<StackPanel> <ContentControl> <AdaptiveTrigger /> </ContentControl> <ContentControl> <Rectangle Height="50" Fill="Red" /> </ContentControl> </StackPanel>
2. ContentTemplate
要將ContentControl的內容按自己的想法顯示出來,可以使用ContentTemplate屬性public DataTemplate ContentTemplate { get; set; })
。DataTemplate是定義如何顯示綁定的數據對象的XAML標記。DataTemplate定義的XAML塊中元素的DataContext相當於所在ContentControl的Content。
下面的示例演示了怎麼將ScoreModel顯示在UI上。
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid.Resources> <DataTemplate x:Key="PassTemplate"> <Border Background="Green"> <TextBlock Text="{Binding Score}" Foreground="White" FontSize="20" Margin="20" HorizontalAlignment="Center" /> </Border> </DataTemplate> </Grid.Resources> <ContentControl ContentTemplate="{StaticResource PassTemplate}"> <local:ScoreModel Score="30" /> </ContentControl> </Grid>
3. ContentTemplateSelector
如果需要根據Content動態地選擇要使用的ContentTemplate,其中一個方法就是 public DataTemplateSelector ContentTemplateSelector { get; set; }
屬性。
要使用ContentTemplateSelector,首先實現一個繼承DataTemplateSelector的類,並重寫protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
函數,在此函數中返回選中的DataTemplate。
以下的示例演示了SimpleDataTemplateSelector的功能,它通過判斷Score是否大於60,從而選擇返回PassTemplate或者FailTemplate。PassTemplate和FailTemplate都是SimpleDataTemplateSelector 的public屬性,並在XAML中注入到SimpleDataTemplateSelector。
public class SimpleDataTemplateSelector : DataTemplateSelector { public DataTemplate PassTemplate { get; set; } public DataTemplate FailTemplate { get; set; } protected override DataTemplate SelectTemplateCore(object item, DependencyObject container) { var model = item as ScoreModel; if (model == null) return null; if (model.Score >= 60) return PassTemplate; else return FailTemplate; } }
<StackPanel> <StackPanel.Resources> <DataTemplate x:Key="PassTemplate"> <Border Background="Green"> <TextBlock Text="{Binding Score}" Foreground="White" FontSize="20" Margin="20" HorizontalAlignment="Center" /> </Border> </DataTemplate> <DataTemplate x:Key="FailTemplate"> <Border Background="Red"> <TextBlock Text="{Binding Score}" Foreground="White" FontSize="20" Margin="20" HorizontalAlignment="Center" /> </Border> </DataTemplate> <local:SimpleDataTemplateSelector PassTemplate="{StaticResource PassTemplate}" FailTemplate="{StaticResource FailTemplate}" x:Key="DataTemplateSelector" /> <Style TargetType="ContentControl"> <Setter Property="ContentTemplateSelector" Value="{StaticResource DataTemplateSelector}" /> </Style> </StackPanel.Resources> <ContentControl> <local:ScoreModel Score="60" /> </ContentControl> <ContentControl> <local:ScoreModel Score="30" /> </ContentControl> </StackPanel>
注意:ContentTemplateSelector的缺點是需要創建多個模板,通常同一組數據的模板只有少部分的差別,可以在同一個模板中通過IValueConverter等方式顯示不同的格式。
4. ContentTransitions
public TransitionCollection ContentTransitions { get; set; }
是類型爲Transition的集合,提供Content改變時的過渡動畫。
<ContentControl x:Name="ContentControl"> <ContentControl.ContentTransitions> <TransitionCollection> <AddDeleteThemeTransition /> </TransitionCollection> </ContentControl.ContentTransitions> </ContentControl>
UWP提供了很多優秀的動畫效果,適當使用可以給人很好的用戶體驗。如果沒有優秀的UI設計,老老實實用默認的ContentTransitions就不會錯。