Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I write a custom picker control in UWP?

I have been fine-combing the web for any guidance, discussions or experience on this and I think I can safely say there’s nothing to be found.

We are developing a set of controls for UWP which we plan to open source and make available for free. One of the controls we are building is a TimeSpanPicker control, which will essentially look and behave like the TimePicker control, but instead of being limited to a time of day (i.e. 24 hour interval) it will allow the user to edit an arbitrary TimeSpan.

From what I have been able to piece together from the visible metadata of the Windows Runtime API, using the built-in TimePicker control for reference, I am realizing the following types of components are involved:

  • The TimePicker control itself which inherits from Control
  • The TimePickerFlyout class which inherits from PickerFlyoutBase
  • The TimePickerFlyoutPresenter control, which inherits from Control

I realize I need to mimic this pattern and write these three components for our picker control, but I can find no information about how these pieces fit together, and from the API surfaces alone I don’t think it’s possible to figure it out.

Specifically, the primary things I’d like to understand are:

  • How is the TimePickerFlyout incorporated into the TimePicker class? I can see no reference to a flyout anywhere within the default template of the picker control.
  • What role does the TimePickerFlyoutPresenter control play, and how is it incorporated into the TimePickerFlyout class? The TimePickerFlyout class has no template – so how does it instantiate and communicate with the TimePickerFlyoutPresenter control?
  • What are the basic steps to mimic this pattern?
  • What is the intended use of the ShouldShowConfirmationButtons and OnConfirmed virtual methods on PickerFlyoutBase? When I override them in my concrete implementation, they are never called.

I’d be very thankful for any guidance!

like image 422
Daniel Rosenberg Avatar asked Oct 30 '22 04:10

Daniel Rosenberg


1 Answers

I had the same prob, but after work around, I did the following to change the TimePickerFlyout's background color and the size of the buttons on its footer and other style as I needed.

Navigate to C:\Program Files (x86)\Windows Kits\10\DesignTime\CommonConfiguration\Neutral\UAP\10.0.10240.0\Generic

(Note this may change depending on your SDK version)

Open the generic.xaml file

Copy the TargetType="TimePickerFlyoutPresenter" section to your App.xaml, and make changes whatever you want, All the Flyouts will be changed accordingly.

OR

Copy this style and put it in 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>
like image 122
Zia Ur Rahman Avatar answered Dec 26 '22 12:12

Zia Ur Rahman