DatePicker 高级版本实现(支持时分秒选择)
WPF 自带日期控件功能太差了,而且Calendar是不可以继承的,思而再三,手撸一个
实现效果
DatePicker.XAML
中间穿插了几个自定义扩展样式(相对比较简单,自行实现)
<ControlTemplate x:Key="IMS.ControlTemplate.DatePick" TargetType="{x:Type DatePicker}">
<Grid x:Name="PART_Root">
<Border
x:Name="Bg"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding ims:IMSAttach.CornerRadius}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<Grid x:Name="PART_InnerGrid" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<ContentControl
x:Name="Label"
Margin="1"
Content="{TemplateBinding ims:TitleAttach.Title}"
IsHitTestVisible="False"
IsTabStop="False"
Template="{TemplateBinding ims:TitleAttach.TitleTemplate}" />
<Border Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentControl
x:Name="PART_AttachContent"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Foreground="{DynamicResource IMS.Brush.Text.Gray}"
Template="{TemplateBinding ims:IMSAttach.AttachContent}" />
</Border>
<ToggleButton
x:Name="PART_DropDownToggle"
Grid.Column="3"
Width="20"
Margin="{TemplateBinding ims:ImageAttach.Margin}"
ims:ImageAttach.Geometry="{TemplateBinding ims:ImageAttach.Geometry}"
ims:ImageAttach.Height="{TemplateBinding ims:ImageAttach.Height}"
ims:ImageAttach.Width="{TemplateBinding ims:ImageAttach.Width}"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
IsTabStop="False"
Style="{DynamicResource IMS.Sys.ToggleButton.Geometry}" />
<Border Grid.Column="1">
<TextBlock
x:Name="Message"
Margin="5,2,5,2"
Padding="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{TemplateBinding Foreground}"
IsHitTestVisible="False"
Opacity="{DynamicResource IMS.Opacity.Watermark}"
Text="{TemplateBinding ims:TextAttach.Watermark}"
TextAlignment="Center"
Visibility="Collapsed" />
</Border>
<Grid Grid.Column="1">
<TextBox
x:Name="PART_TextBox"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Stretch"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}"
IsHitTestVisible="True"
IsReadOnly="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Style="{DynamicResource IMS.Sys.TextBox.Editable}"
Text="{Binding Path=SelectedDate, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}, StringFormat={DynamicResource IMS.DateTimeFormat}}" />
</Grid>
<Popup
x:Name="PART_Popup"
AllowsTransparency="True"
Placement="Bottom"
PlacementTarget="{Binding ElementName=PART_DropDownToggle}"
StaysOpen="False" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
</DataTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Opacity" Value="{DynamicResource IMS.Opacity.Disable}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="PART_AttachContent" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="PART_DropDownToggle" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="Message" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(ims:BrushAttach.SelectedBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="PART_AttachContent" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="PART_DropDownToggle" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(ims:BrushAttach.SelectedBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="PART_AttachContent" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="PART_DropDownToggle" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="Message" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<ControlTemplate x:Key="IMS.ControlTemplate.DatePick.Single" TargetType="{x:Type DatePicker}">
<Grid x:Name="PART_Root">
<Grid x:Name="PART_InnerGrid" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Border
x:Name="Bg"
Grid.Column="1"
Grid.ColumnSpan="3"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding ims:IMSAttach.CornerRadius}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<ContentControl
x:Name="Label"
Margin="1"
Content="{TemplateBinding ims:TitleAttach.Title}"
IsTabStop="False" />
<Border Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Center">
<ContentControl
x:Name="PART_AttachContent"
VerticalAlignment="Center"
VerticalContentAlignment="Center"
Foreground="{DynamicResource IMS.Brush.Text.Gray}"
Template="{TemplateBinding ims:IMSAttach.AttachContent}" />
</Border>
<ToggleButton
x:Name="PART_DropDownToggle"
Grid.Column="3"
Width="35"
Margin="{TemplateBinding ims:ImageAttach.Margin}"
ims:ImageAttach.Geometry="{TemplateBinding ims:ImageAttach.Geometry}"
ims:ImageAttach.Height="{TemplateBinding ims:ImageAttach.Height}"
ims:ImageAttach.Width="{TemplateBinding ims:ImageAttach.Width}"
IsChecked="{Binding IsDropDownOpen, Mode=TwoWay, RelativeSource={RelativeSource TemplatedParent}}"
IsTabStop="False"
Style="{DynamicResource IMS.Sys.ToggleButton.Geometry}" />
<Border Grid.Column="1">
<TextBlock
x:Name="Message"
Margin="5,2,5,2"
Padding="0"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{TemplateBinding Foreground}"
IsHitTestVisible="False"
Opacity="{DynamicResource IMS.Opacity.Watermark}"
Text="{TemplateBinding ims:TextAttach.Watermark}"
TextAlignment="Center"
Visibility="Collapsed" />
</Border>
<Grid Grid.Column="1">
<TextBox
x:Name="PART_TextBox"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Stretch"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
Foreground="{TemplateBinding Foreground}"
IsHitTestVisible="True"
IsReadOnly="True"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
Style="{DynamicResource IMS.Sys.TextBox.Editable}"
Text="{Binding Path=SelectedDate, Mode=OneWay, RelativeSource={RelativeSource TemplatedParent}, StringFormat={StaticResource IMS.DateTimeFormat}}" />
</Grid>
<Popup
x:Name="PART_Popup"
AllowsTransparency="True"
Placement="Bottom"
PlacementTarget="{Binding ElementName=PART_Root}"
StaysOpen="False" />
</Grid>
</Grid>
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=Text}" Value="">
<Setter TargetName="Message" Property="Visibility" Value="Visible" />
</DataTrigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_Root" Property="Opacity" Value="{StaticResource IMS.Opacity.Disable}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="Label" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="PART_AttachContent" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="PART_DropDownToggle" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="Message" Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter Property="Foreground" Value="{Binding Path=(ims:BrushAttach.MouseOverBorderBrush), RelativeSource={RelativeSource Self}}" />
</Trigger>
<Trigger Property="IsFocused" Value="True">
<Setter TargetName="Label" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="PART_AttachContent" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter Property="BorderBrush" Value="{Binding Path=(ims:BrushAttach.SelectedBorderBrush), RelativeSource={RelativeSource Self}}" />
</Trigger>
<Trigger Property="IsKeyboardFocusWithin" Value="True">
<Setter Property="BorderBrush" Value="{Binding Path=(ims:BrushAttach.SelectedBorderBrush), RelativeSource={RelativeSource Self}}" />
<Setter TargetName="Label" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="PART_AttachContent" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="PART_DropDownToggle" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter TargetName="Message" Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Style x:Key="IMS.Sys.DatePicker" TargetType="{x:Type DatePicker}">
<Setter Property="SelectedDate" Value="{x:Static sys:DateTime.Now}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text.Gray}" />
<Setter Property="Background" Value="{DynamicResource IMS.Brush.Text.White}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="ims:ImageAttach.Geometry" Value="{DynamicResource IMS.Geometry.CalendarGeometry}" />
<Setter Property="BorderBrush" Value="{DynamicResource IMS.Brush.Text.White}" />
<Setter Property="ims:BrushAttach.SelectedBorderBrush" Value="{DynamicResource IMS.Brush.Text}" />
<Setter Property="ims:BrushAttach.MouseOverBorderBrush" Value="{DynamicResource IMS.Brush.Title.2}" />
<Setter Property="ims:BrushAttach.SelectedBackground" Value="{DynamicResource IMS.Brush.Text}" />
<Setter Property="ims:ImageAttach.Margin" Value="0,-2,0,0" />
<Setter Property="ims:IMSAttach.CornerRadius" Value="5" />
<Setter Property="FontSize" Value="{DynamicResource IMS.FontSize.Default}" />
<Setter Property="MinHeight" Value="26" />
<Setter Property="Height" Value="{DynamicResource IMS.Row.Height.Middle}" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Margin" Value="{DynamicResource IMS.Padding.Text}" />
<Setter Property="HorizontalContentAlignment" Value="Stretch" />
<Setter Property="IsTodayHighlighted" Value="True" />
<Setter Property="Padding" Value="10,0,0,0" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="CalendarStyle" Value="{DynamicResource IMS.Sys.Calendar}" />
<Setter Property="Template" Value="{DynamicResource IMS.ControlTemplate.DatePick}" />
<Setter Property="RenderTransform" Value="{StaticResource IMS.Wpf.TransformGroup.Default}" />
</Style>
Calendar XAML
中间穿插了几个自定义扩展样式(相对比较简单,自行实现)
<Style x:Key="IMS.Sys.CalendarDayButton" TargetType="CalendarDayButton">
<Setter Property="MinWidth" Value="28" />
<Setter Property="MinHeight" Value="5" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Title.Gray}" />
<Setter Property="Margin" Value="0" />
<Setter Property="IsTabStop" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarDayButton">
<Grid x:Name="Grid" Margin="{TemplateBinding Margin}">
<Border x:Name="Bg" Background="{TemplateBinding Background}" />
<ContentPresenter
x:Name="NormalText"
Margin="5,2,5,2"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
TextElement.Foreground="{TemplateBinding Foreground}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{DynamicResource IMS.Brush.Title.1}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text.White.1}" />
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
<Trigger Property="IsToday" Value="True">
<Setter Property="FontWeight" Value="Bold" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource IMS.Brush.Title}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text.White.1}" />
</Trigger>
<!-- 不可用日期 -->
<Trigger Property="IsBlackedOut" Value="True">
<Setter TargetName="Grid" Property="Opacity" Value="{StaticResource IMS.Opacity.Disable}" />
</Trigger>
<!-- 不在当月的日期 -->
<Trigger Property="IsInactive" Value="True">
<Setter TargetName="Grid" Property="Opacity" Value="0.65" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Grid" Property="Opacity" Value="{StaticResource IMS.Opacity.Disable}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="IMS.Sys.CalendarItem" TargetType="CalendarItem">
<Setter Property="Margin" Value="0,1,0,1" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarItem">
<ControlTemplate.Resources>
<!-- 头部星期样式 -->
<DataTemplate x:Key="{x:Static CalendarItem.DayTitleTemplateResourceKey}">
<TextBlock
Margin="0,6,0,6"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="{StaticResource IMS.FontSize.Default}"
FontWeight="Bold"
Foreground="{DynamicResource IMS.Brush.Title.Gray}"
Opacity="0.8"
Text="{Binding}" />
</DataTemplate>
</ControlTemplate.Resources>
<Grid x:Name="PART_Root">
<Border
Margin="{TemplateBinding Margin}"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="1">
<Grid Margin="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
<RowDefinition Height="auto" />
</Grid.RowDefinitions>
<!-- Header -->
<Grid Grid.Row="0" HorizontalAlignment="Stretch" Background="{DynamicResource IMS.Brush.Title.1}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="2*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button
x:Name="PART_HeaderButton"
Grid.Column="1"
ims:BrushAttach.MouseOverForeground="{DynamicResource IMS.Brush.Text.White.1}"
Background="Transparent"
Focusable="False"
FontWeight="Bold" />
<Button
x:Name="PART_PreviousButton"
Grid.Column="0"
Height="20"
ims:BrushAttach.MouseOverForeground="{DynamicResource IMS.Brush.Text.White.1}"
ims:ImageAttach.Geometry="{DynamicResource IMS.Geometry.PageNavigationBack}"
Background="Transparent"
Content=""
Focusable="False"
Foreground="{DynamicResource IMS.Brush.Text.White.1}"
Style="{DynamicResource IMS.Sys.GeometryButton}" />
<Button
x:Name="PART_NextButton"
Grid.Column="2"
Height="20"
ims:BrushAttach.MouseOverForeground="{DynamicResource IMS.Brush.Text.White.1}"
ims:ImageAttach.Geometry="{DynamicResource IMS.Geometry.PageNavigationNext}"
Background="Transparent"
Content=""
Focusable="False"
Foreground="{DynamicResource IMS.Brush.Text.White.1}"
Style="{DynamicResource IMS.Sys.GeometryButton}" />
</Grid>
<!-- PART_MonthView -->
<Grid
x:Name="PART_MonthView"
Grid.Row="1"
Margin="6,1,6,6"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Visibility="Visible">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>
<!-- PART_YearView -->
<Grid
x:Name="PART_YearView"
Grid.Row="1"
Margin="6,10,6,10"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Visibility="Hidden">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
</Grid>
<ims:DashedBorder
x:Name="PART_DashedBorderTime"
Grid.Row="2"
Height="30"
Margin="8,0,8,0"
Background="Transparent"
BorderBrush="Green"
BorderThickness="0,1,0,0"
Visibility="{Binding ElementName=PART_MonthView, Path=Visibility}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="时间" />
<ims:DashedBorder
Height="25"
Margin="5,0"
Background="White"
BorderBrush="Blue"
BorderThickness="1">
<StackPanel Orientation="Horizontal">
<Button
x:Name="PART_BtnHour"
ims:CalendarAttach.IsHourButton="True"
Background="Transparent"
BorderThickness="0"
Command="ims:CalendarAttach.HourCommand"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DatePicker}}}"
Content="00" />
<TextBlock Text=":" />
<Button
x:Name="PART_BtnMinute"
ims:CalendarAttach.IsMinuteButton="True"
Background="Transparent"
BorderThickness="0"
Command="ims:CalendarAttach.MinuteCommand"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DatePicker}}}"
Content="00" />
<TextBlock Text=":" />
<Button
x:Name="PART_BtnSecond"
ims:CalendarAttach.IsSecondButton="True"
Background="Transparent"
BorderThickness="0"
Command="ims:CalendarAttach.SecondCommand"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DatePicker}}}"
Content="00" />
</StackPanel>
</ims:DashedBorder>
<Button
Margin="5,0"
ims:CalendarAttach.IsCurTimeButton="True"
Command="ims:CalendarAttach.CurTimeCommand"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DatePicker}}}"
Content="当前" />
<Button
Margin="0,0,5,0"
ims:CalendarAttach.IsMakeSureButton="True"
Command="ims:CalendarAttach.MakeSureCommand"
CommandParameter="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DatePicker}}}"
Content="确定" />
</StackPanel>
</ims:DashedBorder>
</Grid>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="PART_Root" Property="Opacity" Value="{StaticResource IMS.Opacity.Disable}" />
</Trigger>
<DataTrigger Binding="{Binding DisplayMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Calendar}}}" Value="Year">
<Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden" />
<Setter TargetName="PART_YearView" Property="Visibility" Value="Visible" />
</DataTrigger>
<DataTrigger Binding="{Binding DisplayMode, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Calendar}}}" Value="Decade">
<Setter TargetName="PART_MonthView" Property="Visibility" Value="Hidden" />
<Setter TargetName="PART_YearView" Property="Visibility" Value="Visible" />
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="IMS.Sys.CalendarButton" TargetType="CalendarButton">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text.White.1}" />
<Setter Property="MinWidth" Value="40" />
<Setter Property="MinHeight" Value="42" />
<Setter Property="FontSize" Value="{StaticResource IMS.FontSize.Default}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="CalendarButton">
<Grid x:Name="Grid" Margin="{TemplateBinding Margin}">
<Border x:Name="Bg" Background="{TemplateBinding Background}" />
<ContentPresenter
x:Name="NormalText"
Margin="5,2,5,2"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
TextElement.Foreground="{TemplateBinding Foreground}" />
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsFocused" Value="True">
<Setter Property="Background" Value="{DynamicResource IMS.Brush.Text.White.1}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Title.1}" />
</Trigger>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{DynamicResource IMS.Brush.Title.1}" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Text.White.1}" />
</Trigger>
<!-- 不在当月的日期 -->
<Trigger Property="IsInactive" Value="True">
<Setter TargetName="Grid" Property="Opacity" Value="0.8" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Grid" Property="Opacity" Value="{StaticResource IMS.Opacity.Disable}" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style x:Key="IMS.Sys.Calendar" TargetType="Calendar">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="{DynamicResource IMS.Brush.Title.1}" />
<Setter Property="CalendarDayButtonStyle" Value="{StaticResource IMS.Sys.CalendarDayButton}" />
<Setter Property="CalendarItemStyle" Value="{StaticResource IMS.Sys.CalendarItem}" />
<Setter Property="CalendarButtonStyle" Value="{StaticResource IMS.Sys.CalendarButton}" />
<Setter Property="Background" Value="{DynamicResource IMS.Brush.Text.White.1}" />
<Setter Property="BorderBrush" Value="{DynamicResource IMS.Brush.Title.1}" />
<Setter Property="BorderThickness" Value="1" />
<Setter Property="FontSize" Value="13" />
<Setter Property="IsTodayHighlighted" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Calendar">
<StackPanel x:Name="PART_Root" HorizontalAlignment="Center" Background="Transparent">
<CalendarItem
x:Name="PART_CalendarItem"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
FontFamily="{TemplateBinding FontFamily}"
FontSize="{TemplateBinding FontSize}"
Style="{TemplateBinding CalendarItemStyle}" />
</StackPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
CalendarAttrach.cs
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Input;
using System.Windows.Media;
namespace XXXX.Wpf
{
public static class CalendarAttach
{
const string PART_BtnHour = "PART_BtnHour";
const string PART_BtnMinute = "PART_BtnMinute";
const string PART_BtnSecond = "PART_BtnSecond";
public static void CreatePopup(Button btn,int number,int lineCount,string title)
{
Border dashedBorder = new Border()
{
BorderThickness = new Thickness(1),
Width = (40 * lineCount) + 10,
Background = Brushes.White,
};
Popup popup = new Popup()
{
StaysOpen = false,
PlacementTarget = btn,
AllowsTransparency = true,
Placement = PlacementMode.Bottom,
};
WrapPanel wrapPanel = new WrapPanel()
{
Orientation = Orientation.Horizontal,
Width = (40 * lineCount)+2
};
Label titleLabel = new Label()
{
Content = title,
HorizontalAlignment = HorizontalAlignment.Center,
VerticalAlignment = VerticalAlignment.Center,
HorizontalContentAlignment = HorizontalAlignment.Center,
VerticalContentAlignment = VerticalAlignment.Center,
Width = (40 * lineCount) + 10,
Foreground = Brushes.Blue,
Height = 30,
FontSize = 15,
Background = Brushes.Gray,
};
wrapPanel.Children.Add(titleLabel);
for (int i = 0; i < number; i++)
{
Button button = new Button()
{
Content = i,
Width = 40,
Height = 40
};
button.Click += (sender, e) =>
{
int value = Convert.ToInt32(((Button)sender).Content);
btn.Content = value < 10 ? "0" + value : value;
popup.IsOpen = false;
};
wrapPanel.Children.Add(button);
}
popup.Child = wrapPanel;
popup.IsOpen = true;
}
static CalendarAttach()
{
HourCommand = new RoutedUICommand();
HourCommandBinding = new CommandBinding(HourCommand);
HourCommandBinding.Executed += (sender,e)=>
{
LoggingService.Info("HourCommand");
CreatePopup(sender as Button, 24, 6, "小时");
};
MinuteCommand = new RoutedUICommand();
MinuteCommandBinding = new CommandBinding(MinuteCommand);
MinuteCommandBinding.Executed += (sender, e) =>
{
LoggingService.Info("MinuteCommand");
CreatePopup(sender as Button, 60, 10, "分钟");
};
SecondCommand = new RoutedUICommand();
SecondCommandBinding = new CommandBinding(SecondCommand);
SecondCommandBinding.Executed += (sender, e) =>
{
LoggingService.Info("SecondCommand");
CreatePopup(sender as Button, 60, 10, "秒");
};
CurTimeCommand = new RoutedUICommand();
CurTimeCommandBinding = new CommandBinding(CurTimeCommand);
CurTimeCommandBinding.Executed += (sender, e) =>
{
LoggingService.Info("CurTimeCommand");
Button btn = sender as Button;
DatePicker datePicker = e.Parameter as DatePicker;
Popup popup = datePicker.GetChild<Popup>("PART_Popup");
Calendar calendar = popup.Child as Calendar;
Button btnHour = calendar.GetChild<Button>(PART_BtnHour);
Button btnMinute = calendar.GetChild<Button>(PART_BtnMinute);
Button btnSecond = calendar.GetChild<Button>(PART_BtnSecond);
if (btn.Content.ToString() == "零点")
{
btnHour.Content = "00";
btnMinute.Content = "00";
btnSecond.Content = "00";
btn.Content = "当前";
btn.Background = Brushes.LightBlue;
}
else
{
DateTime dt = DateTime.Now;
btnHour.Content = dt.Hour.ToString().PadLeft(2, '0');
btnMinute.Content = dt.Minute.ToString().PadLeft(2, '0');
btnSecond.Content = dt.Second.ToString().PadLeft(2, '0');
btn.Content = "零点";
btn.Background = Brushes.LightGreen;
}
};
MakeSureCommand = new RoutedUICommand();
MakeSureCommandBinding = new CommandBinding(MakeSureCommand);
MakeSureCommandBinding.Executed += (sender, e) =>
{
LoggingService.Info("MakeSureCommand");
Button btn = sender as Button;
DatePicker datePicker = e.Parameter as DatePicker;
Popup popup = datePicker.GetChild<Popup>("PART_Popup");
Calendar calendar = popup.Child as Calendar;
Button btnHour = calendar.GetChild<Button>(PART_BtnHour);
Button btnMinute = calendar.GetChild<Button>(PART_BtnMinute);
Button btnSecond = calendar.GetChild<Button>(PART_BtnSecond);
DateTime CurDateTime = Convert.ToDateTime(datePicker.SelectedDate == null ? DateTime.Now.Date : datePicker.SelectedDate);
string timeStr = btnHour.Content + ":" + btnMinute.Content + ":" + btnSecond.Content;
CurDateTime = Convert.ToDateTime(CurDateTime.ToString("yyyy-MM-dd") + " " + timeStr);
datePicker.SelectedDate = CurDateTime;
};
}
private static void Btn_Click(object sender, RoutedEventArgs e)
{
throw new System.NotImplementedException();
}
public static RoutedUICommand HourCommand { get; private set; }
public static RoutedUICommand MinuteCommand { get; private set; }
public static RoutedUICommand SecondCommand { get; private set; }
public static RoutedUICommand CurTimeCommand { get; private set; }
public static RoutedUICommand MakeSureCommand { get; private set; }
private static readonly CommandBinding HourCommandBinding;
private static readonly CommandBinding MinuteCommandBinding;
private static readonly CommandBinding SecondCommandBinding;
private static readonly CommandBinding CurTimeCommandBinding;
private static readonly CommandBinding MakeSureCommandBinding;
public static bool GetIsHourButton(DependencyObject obj)
{
return (bool)obj.GetValue(IsHourButtonProperty);
}
public static void SetIsHourButton(DependencyObject obj, bool value)
{
obj.SetValue(IsHourButtonProperty, value);
}
public static readonly DependencyProperty IsHourButtonProperty =
DependencyProperty.RegisterAttached("IsHourButton", typeof(bool), typeof(CalendarAttach),
new PropertyMetadata(SharedInstances.BoxedFalse, (d, e) =>
{
if (e.OldValue != e.NewValue && d is Button button)
{
button.CommandBindings.Add(HourCommandBinding);
}
}));
public static bool GetIsMinuteButton(DependencyObject obj)
{
return (bool)obj.GetValue(IsMinuteButtonProperty);
}
public static void SetIsMinuteButton(DependencyObject obj, bool value)
{
obj.SetValue(IsMinuteButtonProperty, value);
}
public static readonly DependencyProperty IsMinuteButtonProperty =
DependencyProperty.RegisterAttached("IsMinuteButton", typeof(bool), typeof(CalendarAttach),
new PropertyMetadata(SharedInstances.BoxedFalse, (d, e) =>
{
if (e.OldValue != e.NewValue && d is Button button)
{
button.CommandBindings.Add(MinuteCommandBinding);
}
}));
public static bool GetIsSecondButton(DependencyObject obj)
{
return (bool)obj.GetValue(IsSecondButtonProperty);
}
public static void SetIsSecondButton(DependencyObject obj, bool value)
{
obj.SetValue(IsSecondButtonProperty, value);
}
public static readonly DependencyProperty IsSecondButtonProperty =
DependencyProperty.RegisterAttached("IsSecondButton", typeof(bool), typeof(CalendarAttach),
new PropertyMetadata(SharedInstances.BoxedFalse,(d,e)=>
{
if (e.OldValue != e.NewValue && d is Button button)
{
button.CommandBindings.Add(SecondCommandBinding);
}
}));
public static bool GetIsCurTimeButton(DependencyObject obj)
{
return (bool)obj.GetValue(IsCurTimeButtonProperty);
}
public static void SetIsCurTimeButton(DependencyObject obj, bool value)
{
obj.SetValue(IsCurTimeButtonProperty, value);
}
public static readonly DependencyProperty IsCurTimeButtonProperty =
DependencyProperty.RegisterAttached("IsCurTimeButton", typeof(bool), typeof(CalendarAttach),
new PropertyMetadata(SharedInstances.BoxedFalse, (d, e) =>
{
if (e.OldValue != e.NewValue && d is Button button)
{
button.CommandBindings.Add(CurTimeCommandBinding);
}
}));
public static bool GetIsMakeSureButton(DependencyObject obj)
{
return (bool)obj.GetValue(IsMakeSureButtonProperty);
}
public static void SetIsMakeSureButton(DependencyObject obj, bool value)
{
obj.SetValue(IsMakeSureButtonProperty, value);
}
public static readonly DependencyProperty IsMakeSureButtonProperty =
DependencyProperty.RegisterAttached("IsMakeSureButton", typeof(bool), typeof(CalendarAttach),
new PropertyMetadata(SharedInstances.BoxedFalse, (d, e) =>
{
if (e.OldValue != e.NewValue && d is Button button)
{
button.CommandBindings.Add(MakeSureCommandBinding);
}
}));
}
}
点个赞,关注一下嘛