Как написать собственный элемент управления выбора в UWP?

Я тщательно прочесывал Интернет в поисках каких-либо указаний, обсуждений или опыта по этому вопросу, и я думаю, что могу с уверенностью сказать, что ничего не нашел.

Мы разрабатываем набор элементов управления для UWP, исходный код которого мы планируем предоставить бесплатно. Один из элементов управления, который мы создаем, — это элемент управления TimeSpanPicker, который будет выглядеть и вести себя как элемент управления TimePicker, но вместо того, чтобы быть ограниченным временем суток (т. е. 24-часовым интервалом), он позволит пользователю редактировать произвольный элемент TimeSpan.

Из того, что мне удалось собрать из видимых метаданных API среды выполнения Windows, используя встроенный элемент управления TimePicker для справки, я понимаю, что задействованы следующие типы компонентов:

  • Сам элемент управления TimePicker, наследуемый от Control
  • Класс TimePickerFlyout, наследуемый от PickerFlyoutBase
  • Элемент управления TimePickerFlyoutPresenter, наследуемый от Control

Я понимаю, что мне нужно сымитировать этот шаблон и написать эти три компонента для нашего элемента управления сборщиком, но я не могу найти информацию о том, как эти части сочетаются друг с другом, и я не думаю, что только на поверхностях API это возможно понять.

В частности, основные вещи, которые я хотел бы понять, это:

  • Как TimePickerFlyout включается в класс TimePicker? Я не вижу ссылки на всплывающее меню в стандартном шаблоне средства выбора.
  • Какую роль играет элемент управления TimePickerFlyoutPresenter и как он включается в класс TimePickerFlyout? У класса TimePickerFlyout нет шаблона — так как же он создает экземпляр и взаимодействует с элементом управления TimePickerFlyoutPresenter?
  • Каковы основные шаги для имитации этого шаблона?
  • Каково предполагаемое использование виртуальных методов ShouldShowConfirmationButtons и OnConfirmed в PickerFlyoutBase? Когда я переопределяю их в своей конкретной реализации, они никогда не вызываются.

Буду очень признателен за любое руководство!


person Daniel Rosenberg    schedule 30.04.2016    source источник
comment
у меня такая же потребность, но ничего не нашел, вы нашли какое-нибудь решение, пожалуйста, поделитесь им здесь.   -  person Zia Ur Rahman    schedule 04.05.2016
comment
Вы когда-нибудь находили решение? Прямо сейчас у меня точно такая же проблема, я пытаюсь создать TimeSpanPicker   -  person äymm    schedule 03.03.2019
comment
@hutattedonmyarm На самом деле я смог завершить этот контроль, я должен был отправить его на GitHub давным-давно. Спасибо, что напомнили мне, я сделаю это в ближайшие выходные и обновлю этот вопрос ответом.   -  person Daniel Rosenberg    schedule 04.03.2019
comment
@äymm Я опубликовал готовый элемент управления TimeSpanPicker. Вы можете найти его здесь: github.com/IDeliverable/UwpControls   -  person Daniel Rosenberg    schedule 30.03.2019


Ответы (2)


У меня была такая же проблема, но после работы я сделал следующее, чтобы изменить цвет фона 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>
person Zia Ur Rahman    schedule 04.05.2016
comment
Когда я смотрел этот пост, я не был хорошо знаком с UWP, поэтому я хотел добавить небольшой момент. Если вы решите поместить скопированный код в свой App.xaml, он должен быть завернут в сторону <Application.Resources>...Your Code Here ...</Application.Resources>. - person ChronoZZ; 14.11.2019

Итак, так как несколько человек попросили меня проследить за этим, я действительно в конечном итоге смог разобраться во всем этом с некоторой помощью Джима Уокера (MSFT). Это было давно, но теперь я решил пересмотреть это и, наконец, закончить те элементы управления TimeSpanPicker и TimeSpanEditor, над которыми я работал.

https://github.com/IDeliverable/UwpControls

Запустите проект TestHost, чтобы увидеть оба элемента управления в действии.

Репозиторий также содержит несколько других элементов управления; часть, содержащая элементы управления TimeSpanPicker и TimeSpanEditor, находится здесь:

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

Мы надеемся, что этот код послужит действительно хорошим образцом для всех, кто интересуется созданием собственного элемента управления выбора, но элементы управления также должны быть полезны для всех, кому необходимо добавить TimeSpan функции редактирования в свое приложение. Я действительно увлекся этими элементами управления, вникая в детали и неочевидные вещи, такие как специальные возможности, поддержка нескольких режимов ввода (сенсорный экран, клавиатура, мышь), соответствие системной теме, полная поддержка шаблонов и т. д.

Документация для этих двух элементов управления в настоящее время находится в стадии разработки.

Я планирую в ближайшее время упаковать эти элементы управления в пакеты NuGet, но пока вам придется использовать их как исходный код. Я также собираюсь проверить, есть ли интерес к их включению в инструментарий сообщества Windows.

person Daniel Rosenberg    schedule 29.03.2019