[UWP 自定义控件]了解模板化控件(2.1):理解ContentControl

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就不会错。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
模板控件可以通过支持Command来实现与应用程序的交互。Command是一种对象,用于表示操作并将其绑定到控件。在模板控件中,可以使用Command来响应用户的交互事件,例如按钮的单击事件。 在UWP中,可以使用ICommand接口来创建Command。ICommand定义了两个方法:CanExecute和Execute。CanExecute方法用于检查Command是否可以执行,而Execute方法用于执行Command。 具体实现时,可以为模板控件添加一个Command属性,然后在控件模板中绑定该属性。例如,可以在Button控件模板中添加一个Command属性,并将其绑定到Button的Command属性。当用户单击按钮时,控件会调用Command的Execute方法,执行相应的操作。 以下是一个简单的示例,演示如何在模板控件中使用Command: ``` public class MyControl : Control { public MyControl() { this.DefaultStyleKey = typeof(MyControl); } public ICommand MyCommand { get { return (ICommand)GetValue(MyCommandProperty); } set { SetValue(MyCommandProperty, value); } } public static readonly DependencyProperty MyCommandProperty = DependencyProperty.Register("MyCommand", typeof(ICommand), typeof(MyControl), new PropertyMetadata(null)); } <Style TargetType="local:MyControl"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="local:MyControl"> <Button Content="Click Me" Command="{TemplateBinding MyCommand}" /> </ControlTemplate> </Setter.Value> </Setter> </Style> ``` 在这个例子中,MyControl添加了一个MyCommand属性,并在控件模板中绑定到一个Button控件的Command属性。当用户单击按钮时,控件会调用MyCommand的Execute方法。 使用模板控件的好处是可以将控件的外观和交互逻辑分离。这样可以使代码更易于维护和扩展。通过支持Command,模板控件可以更好地与应用程序的交互进行整合,实现更复杂的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值