先上截圖 修正2 源代碼 修正: 應該將SetTime方法修改為,行號為207行開始修改 var nk = Day_of_week(year, month, 1); if (nk == 0) nk = 7; for (var i = 0; i < nk-1; i++) { Time.Add(new ...
先上截圖
修正2
修正:
應該將SetTime方法修改為,行號為207行開始修改
var nk = Day_of_week(year, month, 1); if (nk == 0) nk = 7; for (var i = 0; i < nk-1; i++) { Time.Add(new BaseTime()); }
整體過程是魔改Listbox,整體是放在用戶控制項中,關於日期的計算是來自這位博友的博文
抱歉沒有過多註釋,原本也只是一時興起,多多見諒
1 修改ListBox的模板
將listbox的模板設為一個三層結果的模板
1 左右日期調整
2 星期顯示
3 當月顯示
其中左右日期調整為按鈕,並實現是命令。星期顯示使用數據提供者進行枚舉綁定,當月顯示即為普通的lisbox面板
2修改ListItem
大部分的改動都是這裡的,一開始想用子項樣式選擇器或者子項模板選擇器來進行動態改變,不過發現不太適合,後來改為數據觸發器動態改變底層矩形顏色。
整體是一個checkbox,利用其屬性來完成選擇過程。
選擇過程是使用棧,保證只有最多兩個選擇項
3添加依賴屬性
保證某些數據能夠被獲取,不過沒有實現路由事件。所以本控制項依舊是一個玩具,不能被直接使用於真實項目
代碼中命名不太規範,請湊乎看。
XAML代碼
<UserControl x:Class="日期控制項.UC_DateTime" 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:local="clr-namespace:日期控制項" xmlns:sys="clr-namespace:System;assembly=mscorlib" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" x:Name="UC_DateTime_" > <UserControl.Resources> <local:AutoWidth x:Key="AutoWidth"/> <ObjectDataProvider x:Key="Week" ObjectType="{x:Type sys:Enum}" MethodName="GetValues" > <ObjectDataProvider.MethodParameters> <x:Type TypeName="local:BaseDateTime"/> </ObjectDataProvider.MethodParameters> </ObjectDataProvider> <local:BaseDate x:Key="Time" /> <local:BaseSelectStyle x:Key="Select"/> <local:DateTimeCombo x:Key="DateTime"/> <local:SelectDateTimeList x:Key="SDT"/> <Style TargetType="local:UC_DateTime"> <Setter Property="SelectDateTime" Value="{Binding Source={StaticResource Time}, Path=SelectDateTimeList}"/> </Style> </UserControl.Resources> <Grid x:Name="GridPanel" Tag="{Binding ElementName=LB,Path=Tag}"> <ListBox Margin="0,0,0,10" x:Name="LB" SelectionMode="Single" BorderBrush="Silver" BorderThickness="0,1,0,1" > <ListBox.ItemsSource> <MultiBinding Converter="{StaticResource DateTime}"> <Binding ElementName="UC_DateTime_" Path="SetYear"/> <Binding ElementName="UC_DateTime_" Path="SetMonth"/> <Binding Source="{StaticResource Time}"/> </MultiBinding> </ListBox.ItemsSource> <ListBox.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=ScrollContentPresenter}, Path=ActualWidth}" ItemWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Width,Converter={StaticResource AutoWidth}}" /> </ItemsPanelTemplate> </ListBox.ItemsPanel> <ListBox.Template> <ControlTemplate TargetType="ListBox"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="auto"/> <RowDefinition Height="auto"/> <RowDefinition Height="*"/> </Grid.RowDefinitions> <Grid Grid.Row="0"> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*" /> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Button x:Name="PreviousButton" Grid.Column="0" Background="Transparent" Command="{Binding Path=PreviousClick, Source={StaticResource Time}}" BorderThickness="0" Content="<" HorizontalContentAlignment="Left" > <Button.CommandParameter> <MultiBinding Converter="{StaticResource DateTime}" ConverterParameter="1"> <Binding ElementName="YEAR" Mode="TwoWay"/> <Binding ElementName="MONTH" Mode="TwoWay"/> </MultiBinding> </Button.CommandParameter> </Button> <TextBlock Grid.Column="1" HorizontalAlignment="Center" > <Run x:Name="YEAR" Text="{Binding ElementName=UC_DateTime_,Path=SetYear}"/> <Run Text="年"/> <Run x:Name="MONTH" Text="{Binding ElementName=UC_DateTime_,Path=SetMonth}"/> <Run Text="月"/> </TextBlock> <Button x:Name="NextButton" Grid.Column="2" Command="{Binding Source={StaticResource Time}, Path=NextClick}" Background="Transparent" BorderThickness="0" Content=">" HorizontalContentAlignment="Right"> <Button.CommandParameter> <MultiBinding Converter="{StaticResource DateTime}" ConverterParameter="1"> <Binding ElementName="YEAR" Mode="TwoWay"/> <Binding ElementName="MONTH" Mode="TwoWay"/> </MultiBinding> </Button.CommandParameter> </Button> </Grid> <ItemsControl Grid.Row="1" ItemsSource="{Binding Source={StaticResource Week}}" > <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel Width="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorLevel=1,AncestorType=ItemsControl}, Path=ActualWidth}" ItemWidth="{Binding RelativeSource={RelativeSource Mode=Self}, Path=Width,Converter={StaticResource AutoWidth}}" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding }" HorizontalAlignment="Center"/> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> <Border Grid.Row="2" Margin="{TemplateBinding Margin}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"> <ScrollViewer Padding="3" VerticalScrollBarVisibility="Hidden"> <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </ScrollViewer> </Border> </Grid> </ControlTemplate> </ListBox.Template> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBoxItem"> <ControlTemplate.Resources> <SolidColorBrush Color="{Binding ElementName=UC_DateTime_, Path=SelectItemListBackGround}" x:Key="ListSelectedColor"/> <SolidColorBrush Color="{Binding ElementName=UC_DateTime_, Path=SelectItemBackGround}" x:Key="SelectedColor"/> </ControlTemplate.Resources> <CheckBox x:Name="cb" IsChecked="{Binding ItemIsSelected,Mode=TwoWay}" ClickMode="Release" Command="{Binding Click,Source={StaticResource Time }}" CommandParameter="{ Binding RelativeSource={RelativeSource Mode=Self}, Path=DataContext}" > <CheckBox.Template> <ControlTemplate> <Grid> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition/> <ColumnDefinition/> </Grid.ColumnDefinitions> <Rectangle Margin="0,2,0,2" Grid.Column="0" Fill="{Binding ElementName=UC_DateTime_, Path=SelectItemListBackGround }" x:Name="LeftBackGround" Visibility="Collapsed"/> <Rectangle Margin="0,2,0,2" Grid.Column="1" Fill="{Binding ElementName=UC_DateTime_, Path=SelectItemListBackGround }" x:Name="RightBackGround" Visibility="Collapsed"/> <Ellipse Grid.ColumnSpan="2" x:Name="bd" Width="{Binding ElementName=UC_DateTime_, Path=BackGroundEllipesSize}" Height="{Binding ElementName=UC_DateTime_, Path=BackGroundEllipesSize}"/> </Grid> <TextBlock x:Name="txt" Text="{Binding Time}" FontSize="{Binding ElementName=UC_DateTime_, Path=DateTimeFontSize}" HorizontalAlignment="Center" VerticalAlignment="Center"/> </Grid> <ControlTemplate.Triggers> <DataTrigger Binding="{Binding Time}" Value="0"> <Setter Property="IsEnabled" Value="False"/> <Setter Property="Text" TargetName="txt" Value=""/> </DataTrigger> <MultiDataTrigger > <MultiDataTrigger.Conditions> <Condition Binding="{Binding ItemIsSelected}" Value="true"/> </MultiDataTrigger.Conditions> <Setter Property="Fill" TargetName="bd" Value="{Binding ElementName=UC_DateTime_, Path=SelectItemBackGround }" /> </MultiDataTrigger> <DataTrigger Binding="{Binding ItemIsSelected}" Value="false"> <Setter Property="Fill" Value="White" TargetName="bd"/> </DataTrigger> <DataTrigger Binding="{Binding BackGroundShowMode}" Value="None"> <Setter TargetName="LeftBackGround" Property="Visibility" Value="Collapsed"/> <Setter TargetName="RightBackGround" Property="Visibility" Value="Collapsed"/> </DataTrigger> <DataTrigger Binding="{Binding BackGroundShowMode}" Value="Right"> <Setter TargetName="LeftBackGround" Property="Visibility" Value="Collapsed"/> <Setter TargetName="RightBackGround" Property="Visibility" Value="Visible"/> </DataTrigger> <DataTrigger Binding="{Binding BackGroundShowMode}" Value="Left"> <Setter TargetName="LeftBackGround" Property="Visibility" Value="Visible"/> <Setter TargetName="RightBackGround" Property="Visibility" Value="Collapsed"/> </DataTrigger> <DataTrigger Binding="{Binding BackGroundShowMode}" Value="Both"> <Setter TargetName="LeftBackGround" Property="Visibility" Value="Visible"/> <Setter TargetName="RightBackGround" Property="Visibility" Value="Visible"/> <Setter Property="Visibility" TargetName="bd" Value="Hidden"/> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </CheckBox.Template> </CheckBox> </ControlTemplate> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> </ListBox> </Grid> </UserControl>
XAML.CS頁面
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace 日期控制項 { /// <summary> /// UC_DateTime.xaml 的交互邏輯 /// </summary> public partial class UC_DateTime : UserControl { public UC_DateTime() { InitializeComponent(); } public static readonly DependencyProperty DateTimeFontSizeProperty = DependencyProperty.Register("DateTimeFontSize", typeof(int), typeof(UC_DateTime), new PropertyMetadata(27)); public int DateTimeFontSize { get => Convert.ToInt32(GetValue(DataContextProperty)); set => SetValue(DataContextProperty, value); } public static readonly DependencyProperty BackGroundEllipesStretchProperty = DependencyProperty.Register("BackGroundEllipesStretch", typeof(Stretch), typeof(UC_DateTime), new PropertyMetadata(Stretch.UniformToFill)); public Stretch BackGroundEllipesStretch { get => (Stretch)GetValue(BackGroundEllipesStretchProperty); set => SetValue(BackGroundEllipesStretchProperty, value); } public static readonly DependencyProperty SelectItemBackGroundProperty = DependencyProperty.Register("SelectItemBackGround", typeof(SolidColorBrush), typeof(UC_DateTime), new PropertyMetadata(new SolidColorBrush(Colors.Red))); public SolidColorBrush SelectItemBackGround { get => (SolidColorBrush)GetValue(SelectItemBackGroundProperty); set => SetValue(SelectItemBackGroundProperty, value); } public static readonly DependencyProperty BackGroundEllipesSizeProperty = DependencyProperty.Register("BackGroundEllipesSize", typeof(double), typeof(UC_DateTime), new PropertyMetadata(25.0)); public double BackGroundEllipesSize { get => Convert.ToDouble(GetValue(BackGroundEllipesSizeProperty)); set => SetValue(BackGroundEllipesSizeProperty, value); } public static readonly DependencyProperty SelectItemListBackGroundProperty = DependencyProperty.Register("SelectItemListBackGround", typeof(SolidColorBrush), typeof(UC_DateTime), new PropertyMetadata(new SolidColorBrush(Colors.Red))); public SolidColorBrush SelectItemListBackGround { get => (SolidColorBrush)GetValue(SelectItemListBackGroundProperty); set => SetValue(SelectItemListBackGroundProperty, value); } public static readonly DependencyProperty BackGroundShowModeProperty = DependencyProperty.Register("BackGroundShowMode", typeof(ShowMode), typeof(UC_DateTime), new PropertyMetadata(ShowMode.None)); public ShowMode BackGroundShowMode { get => (ShowMode)GetValue(BackGroundShowModeProperty); set => SetValue(BackGroundShowModeProperty, value); } public static readonly DependencyProperty SetYearProperty = DependencyProperty.Register("SetYear", typeof(int), typeof(UC_DateTime), new PropertyMetadata(DateTime.Now.Year)); public int SetYear { get => Convert.ToInt32(GetValue(SetYearProperty)); set => SetValue(SetYearProperty, value); } public static readonly DependencyProperty SetMonthProperty = DependencyProperty.Register("SetMonth", typeof(int), typeof(UC_DateTime), new PropertyMetadata(DateTime.Now.Month)); public int SetMonth { get => Convert.ToInt32(GetValue(SetMonthProperty)); set => SetValue(SetMonthProperty, value); } //DateTime.Parse(DateTime.Now.ToString("yyyy-MM-dd")) public static readonly DependencyProperty SelectDateTimePropery = DependencyProperty.Register("SelectDateTime", typeof(List<DateTime>), typeof(UC_DateTime), new PropertyMetadata( new List<DateTime>() { })); public List<DateTime> SelectDateTime { get => (List<DateTime>)GetValue(SelectDateTimePropery); set => SetValue(SelectDateTimePropery, value); } } }
最重要的視覺模型類
using System; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Runtime.CompilerServices; using System.Text; using System.Threading.Tasks; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; namespace 日期控制項 { public class ClickCommand : ICommand { public event EventHandler CanExecuteChanged; public bool CanExecute(object parameter) { return true; } public void Execute(object parameter) { if (parameter != null) Action?.Invoke(parameter); else NoParameterAction?.Invoke(); } private Action NoParameterAction; private Action<object> Action; public ClickCommand(Action<object> acion) { this.Action = acion; } public ClickCommand(Action action) { this.NoParameterAction = action; } } public enum BaseDateTime { 周一, 周二, 周三, 周四, 周五, 周六, 周日, } public enum ShowMode { Left, Right, Both, None } public class BaseTime : INotifyPropertyChanged { private int