UWP - DatePicker和TimePicker定制
我想在同一行(水平)上使用DatePicker和TimePicker。我的问题是这些控件太宽。所以我定制了它们以减少内容,但由于弹出窗口太宽,我无法缩小宽度。所以我搜索了一种方法来定制弹出窗口或为控件和弹出窗口设置不同的大小。UWP - DatePicker和TimePicker定制
这里是我的DatePicker风格:
<Style TargetType="DatePicker">
<Setter Property="Orientation" Value="Horizontal"/>
<Setter Property="IsTabStop" Value="False"/>
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Foreground" Value="{ThemeResource SystemControlForegroundBaseHighBrush}"/>
<Setter Property="HorizontalAlignment" Value="Left"/>
<Setter Property="VerticalAlignment" Value="Center"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DatePicker">
<StackPanel x:Name="LayoutRoot" Margin="{TemplateBinding Padding}">
<StackPanel.Resources>
<Style x:Key="DatePickerFlyoutButtonStyle" TargetType="Button">
<Setter Property="UseSystemFocusVisuals" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid Background="{TemplateBinding Background}">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="PointerOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlPageBackgroundAltMediumBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlBackgroundBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="BorderBrush">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightListAccentLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlHighlightAltBaseHighBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused" />
<VisualState x:Name="PointerFocused" />
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="ContentPresenter"
BorderBrush="{TemplateBinding BorderBrush}"
Background="{ThemeResource SystemControlBackgroundAltMediumLowBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
Content="{TemplateBinding Content}"
Foreground="{TemplateBinding Foreground}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
AutomationProperties.AccessibilityView="Raw"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</StackPanel.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Disabled">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter"
Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseMediumLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="FirstPickerSpacing"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="SecondPickerSpacing"
Storyboard.TargetProperty="Fill">
<DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource SystemControlDisabledBaseLowBrush}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="HeaderContentPresenter"
x:DeferLoadStrategy="Lazy"
Visibility="Collapsed"
Content="{TemplateBinding Header}"
ContentTemplate="{TemplateBinding HeaderTemplate}"
Margin="0,0,0,8"
Foreground="{ThemeResource SystemControlForegroundBaseHighBrush}"
AutomationProperties.AccessibilityView="Raw"
BorderBrush="{TemplateBinding BorderBrush}"/>
<Button x:Name="FlyoutButton"
Style="{StaticResource DatePickerFlyoutButtonStyle}"
Foreground="{TemplateBinding Foreground}"
Background="{TemplateBinding Background}"
IsEnabled="{TemplateBinding IsEnabled}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Stretch"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid x:Name="FlyoutButtonContentGrid"
HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" x:Name="DayColumn" />
<ColumnDefinition Width="Auto" x:Name="FirstSpacerColumn" />
<ColumnDefinition Width="Auto" x:Name="MonthColumn" />
<ColumnDefinition Width="Auto" x:Name="SecondSpacerColumn" />
<ColumnDefinition Width="Auto" x:Name="YearColumn" />
</Grid.ColumnDefinitions>
<TextBlock x:Name="DayTextBlock" Text="Day" TextAlignment="Center" Margin="4" FontFamily="{TemplateBinding FontFamily}" FontWeight="{TemplateBinding FontWeight}" FontSize="{TemplateBinding FontSize}" AutomationProperties.AccessibilityView="Raw"/>
<TextBlock x:Name="MonthTextBlock" Text="Month" TextAlignment="Left" Margin="4" FontFamily="{TemplateBinding FontFamily}" FontWeight="{TemplateBinding FontWeight}" FontSize="{TemplateBinding FontSize}" AutomationProperties.AccessibilityView="Raw"/>
<TextBlock x:Name="YearTextBlock" Text="Year" TextAlignment="Center" Margin="4" FontFamily="{TemplateBinding FontFamily}" FontWeight="{TemplateBinding FontWeight}" FontSize="{TemplateBinding FontSize}" AutomationProperties.AccessibilityView="Raw"/>
</Grid>
</Button>
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
要自定义弹出,我们可以编辑的DatePickerFlyoutPresenter和TimePickerFlyoutPresenter的风格和模板。我们可以在Windows SDK安装中的generic.xaml文件夹中找到这些样式,该文件位于\(Program Files)\ Windows Kits \ 10 \ DesignTime \ CommonConfiguration \ Neutral \ UAP \ 10.0.14393.0 \ Generic文件夹中。对于不同的SDK版本,路径不同,风格和资源可能有不同的值。在14393使用DatePickerFlyoutPresenter
的默认样式例如:
<!-- Default style for Windows.UI.Xaml.Controls.DatePickerFlyoutPresenter -->
<Style TargetType="DatePickerFlyoutPresenter">
<Setter Property="Width" Value="296" />
<Setter Property="MinWidth" Value="296" />
<Setter Property="MaxHeight" Value="398" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="FontFamily" Value="{ThemeResource ContentControlThemeFontFamily}" />
<Setter Property="FontWeight" Value="Normal" />
<Setter Property="FontSize" Value="{ThemeResource ControlContentThemeFontSize}" />
<Setter Property="Background" Value="{ThemeResource DatePickerFlyoutPresenterBackground}" />
<Setter Property="AutomationProperties.AutomationId" Value="DatePickerFlyoutPresenter" />
<Setter Property="BorderBrush" Value="{ThemeResource DatePickerFlyoutPresenterBorderBrush}" />
<Setter Property="BorderThickness" Value="{ThemeResource DateTimeFlyoutBorderThickness}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DatePickerFlyoutPresenter">
<Border x:Name="Background"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
MaxHeight="398">
<Grid x:Name="ContentPanel">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid x:Name="PickerHostGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="78*" x:Name="DayColumn" />
<ColumnDefinition Width="Auto" x:Name="FirstSpacerColumn" />
<ColumnDefinition Width="132*" x:Name="MonthColumn" />
<ColumnDefinition Width="Auto" x:Name="SecondSpacerColumn" />
<ColumnDefinition Width="78*" x:Name="YearColumn" />
</Grid.ColumnDefinitions>
<Rectangle x:Name="HighlightRect"
Fill="{ThemeResource DatePickerFlyoutPresenterHighlightFill}"
Grid.Column="0"
Grid.ColumnSpan="5"
VerticalAlignment="Center"
Height="44" />
<Rectangle x:Name="FirstPickerSpacing"
Fill="{ThemeResource DatePickerFlyoutPresenterSpacerFill}"
HorizontalAlignment="Center"
Width="2"
Grid.Column="1" />
<Rectangle x:Name="SecondPickerSpacing"
Fill="{ThemeResource DatePickerFlyoutPresenterSpacerFill}"
HorizontalAlignment="Center"
Width="2"
Grid.Column="3" />
</Grid>
<Grid Grid.Row="1" Height="45" x:Name="AcceptDismissHostGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Height="2"
VerticalAlignment="Top"
Fill="{ThemeResource DatePickerFlyoutPresenterSpacerFill}"
Grid.ColumnSpan="2" />
<Button x:Name="AcceptButton"
Grid.Column="0"
Content=""
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=""
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>
我们可以改变Grid.ColumnDefinitions
减少宽度。
但请注意,虽然和MinWidth
属性中有DatePickerFlyoutPresenter
,但更改它们没有任何影响。 DatePickerFlyoutPresenter
的宽度由DatePicker决定。它们具有相同的宽度。如果我们更改DatePicker的宽度,则弹出窗口会自动调整其宽度。
此外,在DatePickerFlyoutPresenter
,我们不能改变ColumnDefinition
的宽度为Auto
就像你在DatePicker
的风格所做的一样。因为在DatePickerFlyoutPresenter
中,“DayColumn”,“MonthColumn”和“YearColumn”填充为LoopingSelector,其中使用面板如Canvas。如果我们将列的宽度设置为Auto
,LoopingSelector
的宽度将为零,并且用户看不到任何内容。
所以可能没有太多东西可以定制,我们最好为DatePicker
设置一个固定的宽度,以确保用户可以在选取器或选取器的弹出框中看到完整的元素。
<DatePicker Width="200" MinWidth="0" />
TimePicker与DatePicker相同。如果你想要更多的灵活性,我会建议使用新的自定义控件。这是一个关于DatePicker calendar custom control for WinRT Xaml的博客。你可以参考博客和the source code on Codeplex来实现你自己的。