【问题标题】:How do I write a custom picker control in UWP?如何在 UWP 中编写自定义选择器控件?
【发布时间】:2016-08-25 17:32:53
【问题描述】:

我一直在仔细梳理网络,以寻求有关这方面的任何指导、讨论或经验,我想我可以肯定地说没有什么可找到的。

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

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

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

我意识到我需要模仿这种模式并为我们的选择器控件编写这三个组件,但我找不到关于这些部分如何组合在一起的信息,而且仅从 API 表面我认为不可能弄清楚出去。

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

  • 如何将TimePickerFlyout 合并到TimePicker 类中?我在选取器控件的默认模板中的任何地方都看不到对浮出控件的引用。
  • TimePickerFlyoutPresenter 控件起什么作用,它是如何合并到TimePickerFlyout 类中的? TimePickerFlyout 类没有模板 - 那么它如何实例化并与 TimePickerFlyoutPresenter 控件通信?
  • 模仿这种模式的基本步骤是什么?
  • PickerFlyoutBase 上的 ShouldShowConfirmationButtonsOnConfirmed 虚拟方法的预期用途是什么?当我在具体实现中覆盖它们时,它们永远不会被调用。

非常感谢您的指导!

【问题讨论】:

  • 有同样的需求,但是没找到,有没有找到解决办法,请分享到这里。
  • 您找到解决方案了吗?现在我遇到了完全相同的问题,我正在尝试创建一个 TimeSpanPicker
  • @hutattedonmyarm 这个控件其实我是可以完成的,早就应该推送到GitHub了。感谢您提醒我,我将在即将到来的周末完成它并用答案更新此问题。
  • @äymm 我现在已经发布了完成的 TimeSpanPicker 控件。你可以在这里找到它:github.com/IDeliverable/UwpControls

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


【解决方案1】:

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

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

(请注意,这可能会因您的 SDK 版本而异)

打开 generic.xaml 文件

TargetType="TimePickerFlyoutPresenter" 部分复制到您的App.xaml,并进行任何您想要的更改,所有Flyouts 都会相应更改。

复制此样式并将其放入 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>

【讨论】:

  • 我在看这篇文章时对 UWP 不是很熟悉,所以我想补充一点。如果您决定将复制的代码放在 App.xaml 中,则必须将其包装在 &lt;Application.Resources&gt;...Your Code Here ...&lt;/Application.Resources&gt; 的一侧
【解决方案2】:

因此,由于有几个人要求我跟进此事,在 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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    • 1970-01-01
    • 1970-01-01
    • 2012-03-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多