一.直接上效果
二.Nuget包
日历、时钟是用的是MaterialDesignThemes的组件,需要安装Nuget包MaterialDesignThemes
三.代码
前台:
<UserControl x:Class="BSDS.DateTimePicker"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:md="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<md:DialogHost DialogTheme="Inherit" Identifier="DateTimePicker">
<DockPanel>
<Grid>
<StackPanel
Orientation="Horizontal">
<TextBox
VerticalAlignment="Center"
VerticalContentAlignment="Center" x:Name="TextShow"
FontSize="{Binding TextBoxFontSize,Mode=TwoWay,RelativeSource={RelativeSource AncestorType=UserControl}}"
Width="{Binding TextBoxWidth,Mode=TwoWay,RelativeSource={RelativeSource AncestorType=UserControl}}"
Height="{Binding TextBoxHeight,Mode=TwoWay,RelativeSource={RelativeSource AncestorType=UserControl}}"
BorderBrush="MediumSeaGreen" BorderThickness="0.5"
Text="{Binding Text,Mode=TwoWay,RelativeSource={RelativeSource AncestorType=UserControl}}"
/>
<Button
Margin="3,0,0,0" Height="{Binding TextBoxHeight,Mode=TwoWay,RelativeSource={RelativeSource AncestorType=UserControl}}"
Command="{x:Static md:DialogHost.OpenDialogCommand}"
Content="...">
<Button.CommandParameter>
<Grid
Margin="-1">
<Grid.RowDefinitions>
<RowDefinition
Height="*" />
<RowDefinition
Height="Auto" />
</Grid.RowDefinitions>
<StackPanel
Height="420"
Width="600"
Grid.Row="0"
Orientation="Horizontal">
<Calendar
x:Name="CombinedCalendar"
Margin="-1,-4,-1,0" />
<md:Clock
FontSize="15"
x:Name="CombinedClock"
DisplayAutomation="CycleWithSeconds"
Is24Hours="True" />
</StackPanel>
<StackPanel
Grid.Row="1"
Margin="8,-30,8,8"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button
Command="{x:Static md:DialogHost.CloseDialogCommand}"
CommandParameter="0"
Content="取消"
Style="{StaticResource MaterialDesignFlatButton}" />
<Button
Content="重置"
Click="Reset"
Style="{StaticResource MaterialDesignFlatButton}" />
<Button
Command="{x:Static md:DialogHost.CloseDialogCommand}"
CommandParameter="1"
Content="确定"
Click="OK"
Style="{StaticResource MaterialDesignFlatButton}" />
</StackPanel>
</Grid>
</Button.CommandParameter>
</Button>
</StackPanel>
</Grid>
</DockPanel>
</md:DialogHost>
</UserControl>
后台:
using System.Windows;
using System.Windows.Controls;
namespace BSDS
{
/// <summary>
/// DateTimePicker.xaml 的交互逻辑
/// </summary>
public partial class DateTimePicker : UserControl
{
public DateTimePicker()
{
InitializeComponent();
CombinedCalendar.SelectedDate = DateTime.Now;
CombinedClock.Time = DateTime.Now;
(Content as FrameworkElement)!.DataContext = this;
}
private bool isUIChangeText;
public static readonly DependencyProperty TextProperty =
DependencyProperty.Register("Text", typeof(string), typeof(DateTimePicker),
new PropertyMetadata(DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss"), (s, e) =>
{
if (s is DateTimePicker dp && dp.isUIChangeText)
{
if (DateTime.TryParse(dp.Text, out DateTime dateTime))
{
dp.CombinedCalendar.SelectedDate =
dp.CombinedClock.Time = dp.DateTime = dateTime;
if (dp.Text != dateTime.ToString("yyyy-MM-dd HH:mm:ss"))
{
dp.isUIChangeText = false;
dp.Text = dateTime.ToString("yyyy-MM-dd HH:mm:ss");
dp.isUIChangeText = true;
}
}
else
{
dp.isUIChangeText = false;
dp.Text = dp.DateTime.ToString("yyyy-MM-dd HH:mm:ss");
dp.isUIChangeText = true;
}
}
}));
public string Text
{
get => (string)GetValue(TextProperty);
set => SetValue(TextProperty, value);
}
public static readonly DependencyProperty DateTimeProperty =
DependencyProperty.Register("DateTime", typeof(DateTime), typeof(DateTimePicker),
new PropertyMetadata(DateTime.Now, (s, e) =>
{
if (s is DateTimePicker dp)
{
dp.CombinedCalendar.SelectedDate = dp.CombinedClock.Time = dp.DateTime;
dp.isUIChangeText = false;
dp.Text = dp.DateTime.ToString("yyyy-MM-dd HH:mm:ss");
dp.isUIChangeText = true;
}
}));
public DateTime DateTime
{
get => (DateTime)GetValue(DateTimeProperty);
set => SetValue(DateTimeProperty, value);
}
public static readonly DependencyProperty TextBoxFontSizeProperty =
DependencyProperty.Register("TextBoxFontSize", typeof(double), typeof(DateTimePicker),
new PropertyMetadata((double)12));
public double TextBoxFontSize
{
get => (double)GetValue(TextBoxFontSizeProperty);
set => SetValue(TextBoxFontSizeProperty, value);
}
public static readonly DependencyProperty TextBoxWidthProperty =
DependencyProperty.Register("TextBoxWidth", typeof(double), typeof(DateTimePicker),
new PropertyMetadata((double)120));
public double TextBoxWidth
{
get => (double)GetValue(TextBoxWidthProperty);
set => SetValue(TextBoxWidthProperty, value);
}
public static readonly DependencyProperty TextBoxHeightProperty =
DependencyProperty.Register("TextBoxHeight", typeof(double), typeof(DateTimePicker),
new PropertyMetadata((double)30));
public double TextBoxHeight
{
get => (double)GetValue(TextBoxHeightProperty);
set => SetValue(TextBoxHeightProperty, value);
}
private void OK(object sender, RoutedEventArgs e)
{
string Date = ((DateTime)CombinedCalendar.SelectedDate!).ToString("yyyy-MM-dd");
string Time = CombinedClock.Time.ToString("HH:mm:ss");
DateTime = DateTime.Parse($"{Date} {Time}");
}
private void Reset(object sender, RoutedEventArgs e)
{
CombinedCalendar.SelectedDate = CombinedClock.Time = DateTime.Now;
}
}
}
四.使用例子
xmlns:self="clr-namespace:BSDS"//xaml引入用户控件所在的程序集(此处是本地BSDS项目下)
<self:DateTimePicker DateTime="{Binding EndTime,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Margin="0,10,0,0" VerticalAlignment="Center"/>