如何在UWP中编写自定义选取器控件?

时间:2016-04-30 16:17:04

标签: xaml win-universal-app flyout uwp-xaml

我一直在精心梳理网络上的任何指导,讨论或经验,我想我可以肯定地说找不到任何东西。

我们正在为UWP开发一套控件,我们计划开源并免费提供。我们正在构建的控件之一是TimeSpanPicker控件,其基本上看起来和行为类似于TimePicker控件,但它不会局限于一天中的某个时间(即24小时间隔),它将允许用户编辑任意TimeSpan

从我可以从Windows运行时API的可见元数据中拼凑起来,使用内置的TimePicker控件作为参考,我意识到涉及以下类型的组件:

  • 继承自Control
  • TimePicker 控件本身
  • 继承自PickerFlyoutBase
  • TimePickerFlyout
  • TimePickerFlyoutPresenter 控件,继承自Control

我意识到我需要模仿这个模式并为我们的选择器控件编写这三个组件,但是我找不到关于这些组件如何组合在一起的信息,而且仅从API表面我不认为可以算出它进行。

具体来说,我想了解的主要内容是:

  • 如何将TimePickerFlyout纳入TimePicker课程?我在选择器控件的默认模板中的任何位置都看不到对弹出窗口的引用。
  • TimePickerFlyoutPresenter控制扮演什么角色,以及如何将其纳入TimePickerFlyout课程? TimePickerFlyout类没有模板 - 那么它如何实例化并与TimePickerFlyoutPresenter控件进行通信?
  • 模仿这种模式的基本步骤是什么?
  • ShouldShowConfirmationButtonsOnConfirmedPickerFlyoutBase虚拟方法的用途是什么?当我在具体实现中覆盖它们时,它们永远不会被调用。

我非常感谢任何指导!

2 个答案:

答案 0 :(得分:0)

我有同样的问题,但在解决之后,我做了以下操作来更改TimePickerFlyout的背景颜色和页脚上的按钮大小以及我需要的其他样式。

导航至C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10240.0\Generic

(请注意,这可能会因您的SDK版本而有所变化)

打开generic.xaml文件

TargetType="TimePickerFlyoutPresenter"部分复制到App.xaml,并根据需要进行更改,所有弹出按钮都会相应更改。

复制此样式并将其放入App.xaml。

<!-- Default style for Windows.UI.Xaml.Controls.TimePickerFlyoutPresenter -->
<Style TargetType="TimePickerFlyoutPresenter">
    <Setter Property="Width" Value="242" />
    <Setter Property="MinWidth" Value="242" />
    <Setter Property="MaxHeight" Value="0" />
    <Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
    <Setter Property="FontWeight" Value="Normal" />
    <Setter Property="IsTabStop" Value="False" />
    <Setter Property="VerticalAlignment" Value="Stretch" />
    <Setter Property="Background" Value="{ThemeResource SystemControlBackgroundChromeMediumLowBrush}" />
    <Setter Property="AutomationProperties.AutomationId" Value="TimePickerFlyoutPresenter" />
    <Setter Property="BorderBrush" Value="{ThemeResource SystemControlForegroundTransparentBrush}" />
    <Setter Property="BorderThickness" Value="{ThemeResource DateTimeFlyoutBorderThickness}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="TimePickerFlyoutPresenter">
                <Border x:Name="Background"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        MaxHeight="396">
                    <Grid x:Name="ContentPanel">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="*" />
                            <RowDefinition Height="44" />
                        </Grid.RowDefinitions>

                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" x:Name="FirstPickerHostColumn" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" x:Name="SecondPickerHostColumn" />
                                <ColumnDefinition Width="Auto" />
                                <ColumnDefinition Width="*" x:Name="ThirdPickerHostColumn" />
                            </Grid.ColumnDefinitions>

                            <Rectangle x:Name="HighlightRect" Fill="{ThemeResource SystemControlHighlightListAccentLowBrush}" Grid.Column="0" Grid.ColumnSpan="5" VerticalAlignment="Center" Height="44" />

                            <Border x:Name="FirstPickerHost" Grid.Column="0" />
                            <Rectangle x:Name="FirstPickerSpacing" Fill="{ThemeResource SystemControlForegroundBaseLowBrush}" HorizontalAlignment="Center" Width="2" Grid.Column="1" />
                            <Border x:Name="SecondPickerHost" Grid.Column="2" />
                            <Rectangle x:Name="SecondPickerSpacing" Fill="{ThemeResource SystemControlForegroundBaseLowBrush}" HorizontalAlignment="Center" Width="2" Grid.Column="3" />
                            <Border x:Name="ThirdPickerHost" Grid.Column="4" />
                        </Grid>

                        <Grid Grid.Row="1" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="*" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Rectangle Height="2" VerticalAlignment="Top" Fill="{ThemeResource SystemControlForegroundBaseLowBrush}" Grid.ColumnSpan="2" />

                            <Button x:Name="AcceptButton" Grid.Column="0" Content="&#xE8FB;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Style="{StaticResource DateTimePickerFlyoutButtonStyle}" Margin="0,2,0,0" />
                            <Button x:Name="DismissButton" Grid.Column="1" Content="&#xE711;" FontFamily="{ThemeResource SymbolThemeFontFamily}" FontSize="16" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Style="{StaticResource DateTimePickerFlyoutButtonStyle}" Margin="0,2,0,0" />
                        </Grid>
                    </Grid>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

答案 1 :(得分:0)

因此,由于有几个人要求我跟进此事,因此在Jim Walker(MSFT)的帮助下,我最终终于能够弄清所有这些东西。已经很长时间了,但是我现在决定重新审视这个问题,并最终完成我正在使用的TimeSpanPickerTimeSpanEditor控件。

https://github.com/IDeliverable/UwpControls

运行TestHost项目以查看两个控件的运行情况。

存储库还包含其他一些控件;包含TimeSpanPickerTimeSpanEditor控件的部分在这里:

https://github.com/IDeliverable/UwpControls/tree/master/src/IDeliverable.Controls.Uwp.TimeSpanPicker

对于对如何构建自定义选择器控件感兴趣的任何人,该代码应有望成为一个很好的示例,但是对于需要向其应用程序添加TimeSpan编辑功能的任何人,该控件也应该是有用的。我真的带着这些控件去了城镇,忙着细节和非显而易见的事情,例如可访问性,对多种输入模式(触摸,键盘,鼠标)的支持,系统主题合规性,全面的模板支持等。

这两个控件的文档目前仍在开发中。

我计划很快将这些控件打包为NuGet包,但是现在,您必须将它们作为源代码使用。我还将检查是否有兴趣将它们合并到Window Community Toolkit中。