DatePicker 高级版实现(支持时分秒选择)

11 篇文章 0 订阅

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);
                    }
                }));
    }
}

点个赞,关注一下嘛

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Daniel大妞

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值