跳到主要内容

github/tai

公开

Tai · Windows 软件与网站使用时长统计。上游 Planshit/Tai 的源码镜像,非灵栈原创;MIT 许可。来源:https://github.com/Planshit/Tai 。本次为手动同步,暂不提供安装包。

浏览文件

DateSelect.cs

369 行 · 10.6 KB历史下载
1using Core.Librarys;
2using System;
3using System.Collections.Generic;
4using System.Diagnostics;
5using System.Linq;
6using System.Runtime.InteropServices;
7using System.Text;
8using System.Threading.Tasks;
9using System.Windows;
10using System.Windows.Controls;
11using System.Windows.Controls.Primitives;
12using System.Windows.Input;
13using System.Windows.Shapes;
14using UI.Controls.DatePickerBar;
15
16namespace UI.Controls.Select
17{
18 public class DayModel
19 {
20 public DateTime Day { get; set; }
21 public string DayText
22 {
23 get
24 {
25 return Day.Day.ToString();
26 }
27 }
28 public bool IsToday
29 {
30 get
31 {
32 return Day.Date == DateTime.Now.Date;
33 }
34 }
35 public bool IsOut
36 {
37 get
38 {
39 return Day.Date > DateTime.Now.Date;
40 }
41 }
42 public bool IsDisabled { get; set; }
43 }
44 public class DateSelect : Control
45 {
46 public DateSelectType SelectType
47 {
48 get { return (DateSelectType)GetValue(SelectTypeProperty); }
49 set { SetValue(SelectTypeProperty, value); }
50 }
51 public static readonly DependencyProperty SelectTypeProperty =
52 DependencyProperty.Register("SelectType",
53 typeof(DateSelectType),
54 typeof(DateSelect),
55 new PropertyMetadata(DateSelectType.Day)
56 );
57 public DateTime Date
58 {
59 get { return (DateTime)GetValue(DateProperty); }
60 set { SetValue(DateProperty, value); }
61 }
62 public static readonly DependencyProperty DateProperty =
63 DependencyProperty.Register("Date",
64 typeof(DateTime),
65 typeof(DateSelect),
66 new PropertyMetadata(DateTime.Now, new PropertyChangedCallback(onDateChanged))
67 );
68
69 private static void onDateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
70 {
71 var control = d as DateSelect;
72 control.Year = control.Date.Year;
73 control.Month = control.Date.Month;
74 control.SelectedDay = control.Date.Date;
75 }
76
77 public int Year
78 {
79 get { return (int)GetValue(YearProperty); }
80 set { SetValue(YearProperty, value); }
81 }
82 public static readonly DependencyProperty YearProperty =
83 DependencyProperty.Register("Year",
84 typeof(int),
85 typeof(DateSelect)
86 );
87
88 public int Month
89 {
90 get { return (int)GetValue(MonthProperty); }
91 set { SetValue(MonthProperty, value); }
92 }
93 public static readonly DependencyProperty MonthProperty =
94 DependencyProperty.Register("Month",
95 typeof(int),
96 typeof(DateSelect)
97 );
98
99 public DayModel Day
100 {
101 get { return (DayModel)GetValue(DayProperty); }
102 set { SetValue(DayProperty, value); }
103 }
104 public static readonly DependencyProperty DayProperty =
105 DependencyProperty.Register("Day",
106 typeof(DayModel),
107 typeof(DateSelect)
108 );
109 public string DateStr
110 {
111 get { return (string)GetValue(DateStrProperty); }
112 set { SetValue(DateStrProperty, value); }
113 }
114 public static readonly DependencyProperty DateStrProperty =
115 DependencyProperty.Register("DateStr",
116 typeof(string),
117 typeof(DateSelect)
118 );
119 public List<DayModel> Days
120 {
121 get { return (List<DayModel>)GetValue(DaysProperty); }
122 set { SetValue(DaysProperty, value); }
123 }
124 public static readonly DependencyProperty DaysProperty =
125 DependencyProperty.Register("Days",
126 typeof(List<DayModel>),
127 typeof(DateSelect)
128 );
129
130 public bool IsOpen
131 {
132 get { return (bool)GetValue(IsOpenProperty); }
133 set { SetValue(IsOpenProperty, value); }
134 }
135 public static readonly DependencyProperty IsOpenProperty =
136 DependencyProperty.Register("IsOpen",
137 typeof(bool),
138 typeof(DateSelect), new PropertyMetadata(new PropertyChangedCallback(OnPropertyChanged)));
139
140 private static void OnPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
141 {
142 var control = d as DateSelect;
143 if (e.Property == IsOpenProperty)
144 {
145 control.HandleHook();
146 }
147 }
148
149 private Win32API.LowLevelKeyboardProc mouseProc;
150 private static IntPtr hookMouseID = IntPtr.Zero;
151 private IntPtr hook;
152 public Command ShowSelectCommand { get; set; }
153 public Command SetYearCommand { get; set; }
154 public Command SetMonthCommand { get; set; }
155 public Command DoneCommand { get; set; }
156
157 private bool IsFirstClick = false;
158 private Border SelectContainer;
159 private DateTime SelectedDay;
160 public DateSelect()
161 {
162 DefaultStyleKey = typeof(DateSelect);
163
164 ShowSelectCommand = new Command(new Action<object>(OnShowSelect));
165 SetYearCommand = new Command(new Action<object>(OnSetYear));
166 SetMonthCommand = new Command(new Action<object>(OnSetMonth));
167 DoneCommand = new Command(new Action<object>(OnDone));
168
169
170 Year = Date.Year;
171 Month = Date.Month;
172
173 //Day = new DayModel()
174 //{
175 // Day = Date.Date,
176 //};
177
178 SelectedDay = Date.Date;
179 mouseProc = HookCallback;
180
181 Unloaded += DateSelect_Unloaded;
182 MouseLeftButtonUp += Select_MouseLeftButtonUp;
183 }
184
185
186
187 private void DateSelect_Unloaded(object sender, RoutedEventArgs e)
188 {
189 Win32API.UnhookWindowsHookEx(hook);
190 }
191
192 private void HandleHook()
193 {
194 if (IsOpen)
195 {
196 // 设置键盘钩子
197 hook = Win32API.SetMouseHook(mouseProc);
198 }
199 else
200 {
201 Win32API.UnhookWindowsHookEx(hook);
202 }
203 }
204 private IntPtr HookCallback(int nCode, IntPtr wParam, IntPtr lParam)
205 {
206
207 if (nCode >= 0)
208 {
209 if (wParam == (IntPtr)Win32API.WM_LBUTTONDBLCLK || wParam == (IntPtr)Win32API.WM_WHEEL)
210 {
211 if (!IsFirstClick)
212 {
213 bool isInControl = IsInControl();
214
215 if (!isInControl)
216 {
217 IsOpen = false;
218 }
219 }
220 IsFirstClick = false;
221 }
222
223 }
224
225 return Win32API.CallNextHookEx(hookMouseID, nCode, wParam, lParam);
226 }
227 private bool IsInControl()
228 {
229 var p = Mouse.GetPosition(SelectContainer);
230 if (p.X < 0 || p.Y < 0 || p.X > SelectContainer.ActualWidth || p.Y > SelectContainer.ActualHeight)
231 {
232 return false;
233 }
234
235
236 return true;
237 }
238 private void OnDone(object obj)
239 {
240
241 Date = new DateTime(Year, Month, Day != null ? int.Parse(Day.DayText) : 1);
242 if (Day != null)
243 {
244 SelectedDay = Day.Day;
245 }
246
247 UpdateDateStr();
248
249 IsOpen = false;
250 }
251
252 private void OnSetMonth(object obj)
253 {
254 int newMonth = Month + int.Parse(obj.ToString());
255 if (newMonth < 1 || newMonth > 12)
256 {
257 return;
258 }
259 Month = newMonth;
260
261 //Day = new DayModel() { Day = new DateTime(Year, Month, 1).Date };
262
263 UpdateDays();
264
265
266 }
267
268 private void OnSetYear(object obj)
269 {
270 int newYear = Year + int.Parse(obj.ToString());
271 if (newYear < 2020 || newYear > DateTime.Now.Year)
272 {
273 return;
274 }
275 Year = newYear;
276
277 //Day = new DayModel() { Day = new DateTime(Year, Month, 1).Date };
278
279 UpdateDays();
280 }
281
282 private void OnShowSelect(object obj)
283 {
284 IsOpen = true;
285
286 IsFirstClick = true;
287 }
288
289 private void SelectContainer_Loaded(object sender, RoutedEventArgs e)
290 {
291 Debug.WriteLine("加载");
292 }
293
294 public override void OnApplyTemplate()
295 {
296 base.OnApplyTemplate();
297
298 SelectContainer = GetTemplateChild("SelectContainer") as Border;
299
300 UpdateDays();
301
302 UpdateDateStr();
303
304
305 }
306
307
308 private void Select_MouseLeftButtonUp(object sender, System.Windows.Input.MouseButtonEventArgs e)
309 {
310 }
311
312 private void UpdateDays()
313 {
314 var list = new List<DayModel>();
315
316 var startDay = new DateTime(Year, Month, 1);
317 var startWeekNum = (int)startDay.DayOfWeek;
318 startWeekNum = startWeekNum == 0 ? 7 : startWeekNum;
319 startWeekNum -= 1;
320
321 // 该月天数
322 int days = DateTime.DaysInMonth(Year, Month);
323 // 该月最后一天的日期
324 var lastDay = new DateTime(Year, Month, days);
325
326 var preAppendDays = new List<DayModel>();
327 // 需要向前补日期
328 for (int i = startWeekNum; i > 0; i--)
329 {
330 var date = startDay.AddDays(-i);
331 preAppendDays.Add(new DayModel()
332 {
333 Day = date.Date,
334 IsDisabled = true,
335 });
336 }
337 list.AddRange(preAppendDays);
338
339 // 当月日期
340 for (int i = 1; i < days + 1; i++)
341 {
342 list.Add(new DayModel() { Day = new DateTime(Year, Month, i).Date });
343 }
344
345 Days = list;
346 Day = list.Where(m => m.Day == SelectedDay).FirstOrDefault();
347 }
348
349 private void UpdateDateStr()
350 {
351 DateStr = Date.ToString("yyyy年MM月dd日");
352 if (Date.Date == DateTime.Now.Date)
353 {
354 DateStr = "今天";
355 }
356 if (SelectType == DateSelectType.Month)
357 {
358 DateStr = Date.ToString("yyyy年MM月");
359
360 }
361 else if (SelectType == DateSelectType.Year)
362 {
363 DateStr = Date.ToString("yyyy年");
364
365 }
366 }
367 }
368
369}