我想在同一行(水平)使用 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的样式和模板。我们可以在 generic.xaml 中找到这些样式,该样式可在 Windows SDK 安装的 \(Program Files)\Windows Kits\DesignTime\CommonConfiguration\Neutral\UAP .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
来减小宽度。
但请注意,虽然
Width
中有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 相同。如果您想要更大的灵活性,我建议使用新的自定义控件。这是关于 WinRT Xaml 的 DatePicker 日历自定义控件 的博客。您可以参考博客和Codeplex上的源代码来实现您自己的。
为了将自定义样式更改应用于 DatePicker 和 TimePicker 的 DatePickerFlyoutPresenter,应将自定义的 DatePickerFlyoutPresenter 样式应用于应用程序级别。我的意思是,自定义更改应该出现在(App.xaml)中,因为 DatePickerFlyoutPresenter 是应用程序级别的弹出窗口。如果应用到页面级别或者控制级别,则不会产生任何效果。
通过更新,根据这篇文章: 日期选择器类
generic.xaml 的默认位置位于此处:
\Users\
\.nuget\packages\microsoft.windowsappsdk\ \lib\uap10.0\Microsoft.UI\Themes\generic.xaml