如何在 DateTimePicker 控件中自定义日历?
How to customize Calendar in DateTimePicker Control?
我觉得这个问题简单明了。下图是我目前的进度。
如您所见,自定义版本是我扩展的DateTimePicker控件。该控件根据 Focused 值更改按钮和边框颜色。下拉日历是我接下来要设计的样式。
我只是不知道从哪里开始,因为没有任何东西可以正常工作。至少边框颜色、字体颜色等我不会改变太多...
有一堆属性会影响日历的显示,比如:
- 日历字体
- CalendarForeColor
- 日历月背景
- 日历标题背景颜色
等等
有关详细信息,请参阅 MSDN。
也就是说,DateTimePicker 控件因 不应用来自这些属性的更改而闻名。它仅在关闭整个表单的视觉样式时才应用它们,然后您会得到带有您选择的应用颜色的丑陋斜面外观——但仍然丑陋。
你有非常的选择。下拉日历是一个 MonthCalendar 控件,当您再次单击下拉按钮 Destroyed 时由 DTP 动态创建,当用户关闭它时。 MonthCalendar 是 common controls 之一,内置于 Windows,用 C++ 编写并存储在 comctl32.dll 中。您的应用程序使用 v6.0 版本,存储在并排缓存中 (c:\windows\winsxs)。 .NET class 只是一个包装器,它不会改变它的外观或工作方式。
值得注意的是,它在 Windows 版本之间变化很大,总是需要注意的地方,它在 Windows 中非常显眼的地方使用。这是用户在安装 Windows 时接触过的第一个常用控件。并用于任务栏上的时钟。 Windows 10 是第一个不再使用的版本,Win8 的外观已冻结并且不太可能再次更改。
如前所述,下拉列表是动态创建的。您可以通过发送 DTM_GETMONTHCAL message 来获取 MonthCalendar window 的句柄,在 DropDown 事件的事件处理程序中执行此操作。那时 window 句柄有效但日历尚不可见,是时候修改它了。
从那里您可以发送 MCM messages to configure the calendar. As you can tell, very slim pickings as far as styling goes. You have MCM_SETCALENDARBORDER to change the border thickness and MCM_SETCOLOR to alter colors. The latter only works if the visual style renderer is disabled, it is not in your app. Technically you can call SetWindowTheme() 以禁用视觉样式渲染器,这样 MCM_SETCOLOR 将再次工作。但这把时钟拨回到2000年,它看起来很像恐龙。
仅此而已,不足以让任何人开心。考虑嵌入 WPF DatePicker 以更好地控制样式。
有类似的问题。毕竟还不错。我的 DatePicker 看起来有点不同,但是根据您的需要调整它不会有问题。
首先 - 创建一个资源字典并在其中添加项目所需的所有样式。
在我的解决方案中,我使用了 2 种样式:
DatePicker 的实际样式;
使用自定义按钮的样式。
以下是代码:
<!-- The IconButtonStyle -->
<Style x:Key="IconButtonStyle"
TargetType="{x:Type Button}">
<!-- set some default values -->
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="VerticalAlignment"
Value="Center" />
<!-- set the visual tree of the control -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<!-- here come the actual sub-controls -->
<Border x:Name="border"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
SnapsToDevicePixels="True"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
Padding="0"
CornerRadius="0,0,0,0">
<Border x:Name="innerBorder"
SnapsToDevicePixels="True"
BorderThickness="1"
Padding="2"
CornerRadius="0,0,0,0">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"
Margin="{TemplateBinding Padding}">
<ContentPresenter.Effect>
<!-- give the content a bit of shadow -->
<DropShadowEffect x:Name="shadow"
ShadowDepth="0"
Opacity="0.7"
BlurRadius="0" />
</ContentPresenter.Effect>
<ContentPresenter.RenderTransform>
<!-- push the content a bit to the left and the top -->
<TranslateTransform x:Name="translation"
X="0"
Y="0" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Border>
</Border>
<ControlTemplate.Triggers>
<!--
the triggers define the reactions to various state
changes
-->
<Trigger Property="IsKeyboardFocused"
Value="true">
<Setter TargetName="innerBorder"
Property="BorderBrush"
Value="Transparent" />
<Setter Property="Background"
Value="Transparent" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
Value="Transparent" />
</Trigger>
<!-- when the control is disabled, just let the background shine through -->
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Opacity"
Value="0.5" />
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<!-- This Trigger manages the Animation of the button's content and its shadow -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="shadow"
Storyboard.TargetProperty="(DropShadowEffect.ShadowDepth)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.X)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.Y)" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="shadow"
Storyboard.TargetProperty="(DropShadowEffect.ShadowDepth)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.X)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.Y)" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Customized Datepicker -->
<Style x:Key="DatePicker" TargetType="{x:Type DatePicker}">
<Setter Property="Foreground" Value="{StaticResource DarkGrayBrush}" />
<Setter Property="Focusable" Value="True" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="IsTodayHighlighted" Value="True" />
<Setter Property="SelectedDateFormat" Value="Short" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!--Set CalendarStyle to DatePickerCalendarStyle.-->
<Setter Property="CalendarStyle"
Value="{DynamicResource DatePickerCalendarStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePicker}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
CornerRadius="0"
Background="Transparent">
<Grid x:Name="PART_Root"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="PART_Button"
Grid.Column="1"
Foreground="{TemplateBinding Foreground}"
Focusable="True"
HorizontalAlignment="Left"
Margin="-24,0,0,0"
Grid.Row="0"
Panel.ZIndex="2"
Padding="0" >
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource IconButtonStyle}">
<Setter Property="Height" Value="23" />
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BlueFadedBrush}" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Image Height="15" VerticalAlignment="Top" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/img/calendarBlue.png"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=PART_Button, Path=IsMouseOver}" Value="True">
<Setter Property="Source" Value="/img/calendarWhite.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Border BorderBrush="{StaticResource BlueBrush}"
BorderThickness="2"
CornerRadius="0"
Padding="0"
Width="150"
Height="23"
Background="{StaticResource WhiteBrush}"
Panel.ZIndex="1">
<DatePickerTextBox x:Name="PART_TextBox"
Grid.Column="0"
Foreground="{TemplateBinding Foreground}"
Focusable="{TemplateBinding Focusable}"
HorizontalContentAlignment="Left"
Grid.Row="0"
VerticalContentAlignment="Center"
BorderThickness="0"
Background="Transparent"
Width="150"
Padding="0">
<!-- Watermark access -->
<DatePickerTextBox.Style>
<Style TargetType="DatePickerTextBox">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<Grid.Resources>
<SolidColorBrush x:Key="WatermarkBrush" Color="#FFAAAAAA"/>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
<VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="Transparent" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement"/>
<ColorAnimation Duration="0" To="Transparent" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="watermark_decorator"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="WatermarkStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unwatermarked"/>
<VisualState x:Name="Watermarked">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Watermark"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="1" Padding="{TemplateBinding Padding}">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="0"/>
<Border x:Name="watermark_decorator" BorderBrush="#FFFFFFFF" BorderThickness="0">
<ContentControl x:Name="PART_Watermark" Focusable="False" IsHitTestVisible="False" Opacity="0" Padding="0">
<ContentControl.Template>
<ControlTemplate>
<TextBlock Text="dd/mm/aaaa" Margin="2,0,0,0"/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Border>
<ScrollViewer x:Name="PART_ContentHost" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="#FF45D6FA" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePickerTextBox.Style>
<!-- Watermark access Ends -->
</DatePickerTextBox>
</Border>
<Grid x:Name="PART_DisabledVisual"
Grid.ColumnSpan="2"
Grid.Column="0"
IsHitTestVisible="False"
Opacity="0"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0"
Fill="#A5FFFFFF"
RadiusY="1"
Grid.Row="0"
RadiusX="1" />
<Rectangle Grid.Column="1"
Fill="#A5FFFFFF"
Height="18"
Margin="3,0,3,0"
RadiusY="1"
Grid.Row="0"
RadiusX="1"
Width="19" />
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
Placement="Bottom"
PlacementTarget="{Binding ElementName=PART_TextBox}"
StaysOpen="False" />
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用法如下:
<DatePicker Style="{StaticResource DatePicker}" />
我觉得这个问题简单明了。下图是我目前的进度。
如您所见,自定义版本是我扩展的DateTimePicker控件。该控件根据 Focused 值更改按钮和边框颜色。下拉日历是我接下来要设计的样式。
我只是不知道从哪里开始,因为没有任何东西可以正常工作。至少边框颜色、字体颜色等我不会改变太多...
有一堆属性会影响日历的显示,比如:
- 日历字体
- CalendarForeColor
- 日历月背景
- 日历标题背景颜色
等等
有关详细信息,请参阅 MSDN。
也就是说,DateTimePicker 控件因 不应用来自这些属性的更改而闻名。它仅在关闭整个表单的视觉样式时才应用它们,然后您会得到带有您选择的应用颜色的丑陋斜面外观——但仍然丑陋。
你有非常的选择。下拉日历是一个 MonthCalendar 控件,当您再次单击下拉按钮 Destroyed 时由 DTP 动态创建,当用户关闭它时。 MonthCalendar 是 common controls 之一,内置于 Windows,用 C++ 编写并存储在 comctl32.dll 中。您的应用程序使用 v6.0 版本,存储在并排缓存中 (c:\windows\winsxs)。 .NET class 只是一个包装器,它不会改变它的外观或工作方式。
值得注意的是,它在 Windows 版本之间变化很大,总是需要注意的地方,它在 Windows 中非常显眼的地方使用。这是用户在安装 Windows 时接触过的第一个常用控件。并用于任务栏上的时钟。 Windows 10 是第一个不再使用的版本,Win8 的外观已冻结并且不太可能再次更改。
如前所述,下拉列表是动态创建的。您可以通过发送 DTM_GETMONTHCAL message 来获取 MonthCalendar window 的句柄,在 DropDown 事件的事件处理程序中执行此操作。那时 window 句柄有效但日历尚不可见,是时候修改它了。
从那里您可以发送 MCM messages to configure the calendar. As you can tell, very slim pickings as far as styling goes. You have MCM_SETCALENDARBORDER to change the border thickness and MCM_SETCOLOR to alter colors. The latter only works if the visual style renderer is disabled, it is not in your app. Technically you can call SetWindowTheme() 以禁用视觉样式渲染器,这样 MCM_SETCOLOR 将再次工作。但这把时钟拨回到2000年,它看起来很像恐龙。
仅此而已,不足以让任何人开心。考虑嵌入 WPF DatePicker 以更好地控制样式。
有类似的问题。毕竟还不错。我的 DatePicker 看起来有点不同,但是根据您的需要调整它不会有问题。
首先 - 创建一个资源字典并在其中添加项目所需的所有样式。
在我的解决方案中,我使用了 2 种样式:
以下是代码:
<!-- The IconButtonStyle -->
<Style x:Key="IconButtonStyle"
TargetType="{x:Type Button}">
<!-- set some default values -->
<Setter Property="Background"
Value="Transparent" />
<Setter Property="BorderBrush"
Value="Transparent" />
<Setter Property="VerticalAlignment"
Value="Center" />
<!-- set the visual tree of the control -->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<!-- here come the actual sub-controls -->
<Border x:Name="border"
Height="{TemplateBinding Height}"
Width="{TemplateBinding Width}"
SnapsToDevicePixels="True"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1"
Padding="0"
CornerRadius="0,0,0,0">
<Border x:Name="innerBorder"
SnapsToDevicePixels="True"
BorderThickness="1"
Padding="2"
CornerRadius="0,0,0,0">
<ContentPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
RecognizesAccessKey="True"
Margin="{TemplateBinding Padding}">
<ContentPresenter.Effect>
<!-- give the content a bit of shadow -->
<DropShadowEffect x:Name="shadow"
ShadowDepth="0"
Opacity="0.7"
BlurRadius="0" />
</ContentPresenter.Effect>
<ContentPresenter.RenderTransform>
<!-- push the content a bit to the left and the top -->
<TranslateTransform x:Name="translation"
X="0"
Y="0" />
</ContentPresenter.RenderTransform>
</ContentPresenter>
</Border>
</Border>
<ControlTemplate.Triggers>
<!--
the triggers define the reactions to various state
changes
-->
<Trigger Property="IsKeyboardFocused"
Value="true">
<Setter TargetName="innerBorder"
Property="BorderBrush"
Value="Transparent" />
<Setter Property="Background"
Value="Transparent" />
</Trigger>
<Trigger Property="IsMouseOver"
Value="true">
<Setter Property="Background"
Value="Transparent" />
</Trigger>
<!-- when the control is disabled, just let the background shine through -->
<Trigger Property="IsEnabled"
Value="false">
<Setter Property="Opacity"
Value="0.5" />
</Trigger>
<Trigger Property="IsPressed"
Value="True">
<!-- This Trigger manages the Animation of the button's content and its shadow -->
<Trigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="shadow"
Storyboard.TargetProperty="(DropShadowEffect.ShadowDepth)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.X)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.Y)" />
</Storyboard>
</BeginStoryboard>
</Trigger.EnterActions>
<Trigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="shadow"
Storyboard.TargetProperty="(DropShadowEffect.ShadowDepth)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.X)" />
<DoubleAnimation Duration="0:0:0"
To="0"
Storyboard.TargetName="translation"
Storyboard.TargetProperty="(TranslateTransform.Y)" />
</Storyboard>
</BeginStoryboard>
</Trigger.ExitActions>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- Customized Datepicker -->
<Style x:Key="DatePicker" TargetType="{x:Type DatePicker}">
<Setter Property="Foreground" Value="{StaticResource DarkGrayBrush}" />
<Setter Property="Focusable" Value="True" />
<Setter Property="VerticalAlignment" Value="Top" />
<Setter Property="VerticalContentAlignment" Value="Top" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Setter Property="IsTodayHighlighted" Value="True" />
<Setter Property="SelectedDateFormat" Value="Short" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<!--Set CalendarStyle to DatePickerCalendarStyle.-->
<Setter Property="CalendarStyle"
Value="{DynamicResource DatePickerCalendarStyle}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePicker}">
<Border BorderThickness="{TemplateBinding BorderThickness}"
Padding="{TemplateBinding Padding}"
CornerRadius="0"
Background="Transparent">
<Grid x:Name="PART_Root"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Button x:Name="PART_Button"
Grid.Column="1"
Foreground="{TemplateBinding Foreground}"
Focusable="True"
HorizontalAlignment="Left"
Margin="-24,0,0,0"
Grid.Row="0"
Panel.ZIndex="2"
Padding="0" >
<Button.Style>
<Style TargetType="{x:Type Button}" BasedOn="{StaticResource IconButtonStyle}">
<Setter Property="Height" Value="23" />
<Setter Property="Background" Value="Transparent" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource BlueFadedBrush}" />
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
<Image Height="15" VerticalAlignment="Top" >
<Image.Style>
<Style TargetType="{x:Type Image}">
<Setter Property="Source" Value="/img/calendarBlue.png"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ElementName=PART_Button, Path=IsMouseOver}" Value="True">
<Setter Property="Source" Value="/img/calendarWhite.png"/>
</DataTrigger>
</Style.Triggers>
</Style>
</Image.Style>
</Image>
</Button>
<Border BorderBrush="{StaticResource BlueBrush}"
BorderThickness="2"
CornerRadius="0"
Padding="0"
Width="150"
Height="23"
Background="{StaticResource WhiteBrush}"
Panel.ZIndex="1">
<DatePickerTextBox x:Name="PART_TextBox"
Grid.Column="0"
Foreground="{TemplateBinding Foreground}"
Focusable="{TemplateBinding Focusable}"
HorizontalContentAlignment="Left"
Grid.Row="0"
VerticalContentAlignment="Center"
BorderThickness="0"
Background="Transparent"
Width="150"
Padding="0">
<!-- Watermark access -->
<DatePickerTextBox.Style>
<Style TargetType="DatePickerTextBox">
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DatePickerTextBox}">
<Grid>
<Grid.Resources>
<SolidColorBrush x:Key="WatermarkBrush" Color="#FFAAAAAA"/>
</Grid.Resources>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
<VisualTransition GeneratedDuration="0:0:0.1" To="MouseOver"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimation Duration="0" To="Transparent" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="ContentElement"/>
<ColorAnimation Duration="0" To="Transparent" Storyboard.TargetProperty="(Border.BorderBrush).(SolidColorBrush.Color)" Storyboard.TargetName="watermark_decorator"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="WatermarkStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unwatermarked"/>
<VisualState x:Name="Watermarked">
<Storyboard>
<DoubleAnimation Duration="0" To="0" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="ContentElement"/>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="PART_Watermark"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisual"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" CornerRadius="1" Opacity="1" Padding="{TemplateBinding Padding}">
<Grid x:Name="WatermarkContent" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}">
<Border x:Name="ContentElement" BorderBrush="#FFFFFFFF" BorderThickness="0"/>
<Border x:Name="watermark_decorator" BorderBrush="#FFFFFFFF" BorderThickness="0">
<ContentControl x:Name="PART_Watermark" Focusable="False" IsHitTestVisible="False" Opacity="0" Padding="0">
<ContentControl.Template>
<ControlTemplate>
<TextBlock Text="dd/mm/aaaa" Margin="2,0,0,0"/>
</ControlTemplate>
</ContentControl.Template>
</ContentControl>
</Border>
<ScrollViewer x:Name="PART_ContentHost" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="0" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Border x:Name="FocusVisual" BorderBrush="#FF45D6FA" CornerRadius="1" IsHitTestVisible="False" Opacity="0"/>
</Grid>
</Border>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</DatePickerTextBox.Style>
<!-- Watermark access Ends -->
</DatePickerTextBox>
</Border>
<Grid x:Name="PART_DisabledVisual"
Grid.ColumnSpan="2"
Grid.Column="0"
IsHitTestVisible="False"
Opacity="0"
Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0"
Fill="#A5FFFFFF"
RadiusY="1"
Grid.Row="0"
RadiusX="1" />
<Rectangle Grid.Column="1"
Fill="#A5FFFFFF"
Height="18"
Margin="3,0,3,0"
RadiusY="1"
Grid.Row="0"
RadiusX="1"
Width="19" />
<Popup x:Name="PART_Popup"
AllowsTransparency="True"
Placement="Bottom"
PlacementTarget="{Binding ElementName=PART_TextBox}"
StaysOpen="False" />
</Grid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
用法如下:
<DatePicker Style="{StaticResource DatePicker}" />