RaUI/Source/RaUI/UI/Rili/PaDateInput.cs
zilinsoft 690d2651f5 ## 📅2025-08-16 星期六更新
### rycUpdate    V1.0.2506.0401
- *.[修复]修复文件替换失败,不会失败提示的BUG。
### RaUI    V4.0.2508.1601
- *.[新增]ChromeTabControl控件支持设置SizeMode属性。
- *.[新增]HotkeyTextBox新增支持传入热键文本进行自动转换。
- *.[新增]ryQuickSQL类新增GetJsonData方法。
- *.[新增]ryQuickSQL类新增DateToTimeStamp属性,导出时自动将时间类型转为时间戳。
- *.[新增]自动更新模块新增支持版本类型,区分正式版和测试版。
- *.[改进]HotkeyTextBox控件渲染方式改成全画布渲染。
- *.[改进]TextBoxEx2开启多行模式后,空文本改成在第一行显示。
- *.[修复]修复截图功能某些情况下会报错的BUG。
- *.[修复]修复HotkeyValue类处理多功能键文本时转换错误的BUG。
- *.[修复]修复RyComboBox控件在某些情况下边框会丢失的BUG。
- *.[修复]修复Hosts类针对删除hosts规则处理出错的BUG。
- *.[修复]修复当升级文件Url无法访问时,升级模块会无限期等待的BUG。
2025-08-16 14:27:11 +08:00

442 lines
16 KiB
C#

using Newtonsoft.Json.Linq;
using ryCommon;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Configuration;
using System.Windows.Forms;
using static RaUI.UI.Rili.FhDateTimePickerEX;
namespace RaUI.UI.Rili
{
/// <summary>
/// 日期输入框
/// </summary>
public partial class PaDateInput : UserControl
{
/// <summary>
/// 日期输入框
/// </summary>
public PaDateInput()
{
InitializeComponent();
this.DoubleBuffered = true;
}
private DateTime _dateTime = DateTime.Now;
/// <summary>
///
/// </summary>
public event OnDateTimeChanged ValueChanged;
/// <summary>
///选中日期时间
/// </summary>
[Description("选中日期时间")]
public DateTime Value
{
get
{
//if (Input_Text.Length>0)
//{
// if (SelectedIndex >= 0 && SelectedIndex < list.Count)
// {
// ChangedData(list[SelectedIndex], Input_Text);
// }
//}
return _dateTime;
}
set
{
if (_dateTime == value) { return; }
Text = value.ToString(dateFormat, CultureInfo.InvariantCulture);
if (_dateTime != value)
{
_dateTime = value;
}
SelectedIndex = -1;
Input_Text = "";
this.Invalidate();
ValueChanged?.Invoke(this, _dateTime);
}
}
private string dateFormat = "yyyy-MM-dd";
/// <summary>
///
/// </summary>
[Description("日期格式化掩码"), Category("SunnyUI")]
[DefaultValue("yyyy-MM-dd")]
public string DateFormat
{
get => dateFormat;
set
{
if (dateFormat == value) { return; }
dateFormat = value;
Text = Value.ToString(dateFormat);
SelectedIndex = -1;
Input_Text = "";
this.Invalidate();
}
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnLostFocus(EventArgs e)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
ChangedData(list[SelectedIndex], Input_Text);
}
base.OnLostFocus(e);
}
internal static int ParseRepeatPattern(string format, int pos, char patternChar)
{
int length = format.Length;
int i;
for (i = pos + 1; i < length && format[i] == patternChar; i++)
{
}
return i - pos;
}
private int SelectedIndex = -1;
private void ChangedData(DateItem item,string input,bool paint=true)
{
SelectedIndex = -1;
if (input.Length == 0) { this.Invalidate(); return; }
Input_Text = "";
if (item.Editable)
{
var value = input.ToInt();
switch (item.Format[0])
{
case 'y':
if (value == 0) { value = this.Value.Year; }
if (input.Length == 2)
{
this.Value = this.Value.AddYears(2000 + value - this.Value.Year);
item.Value = 2000 + value;
}
else
{
item.Value = value;
this.Value = this.Value.AddYears(value - this.Value.Year);
}
break;
case 'M':
if (value.IsInRange(1, 12))
{
item.Value = value;
this.Value = this.Value.AddMonths(value - this.Value.Month);
}
break;
case 'd':
if (value.IsInRange(1, 31))
{
if (value <= RyDate.GetMonthStart(this.Value).AddMonths(1).AddDays(-1).Day)
{
item.Value = value;
this.Value = this.Value.AddDays(value - this.Value.Day);
}
}
break;
case 'H':
case 'h':
if (value.IsInRange(0, 59))
{
item.Value = value;
this.Value = this.Value.AddHours(value - this.Value.Hour);
}
break;
case 'm':
if (value.IsInRange(0, 59))
{
item.Value = value;
this.Value = this.Value.AddMinutes(value - this.Value.Minute);
}
break;
case 's':
if (value.IsInRange(0, 59))
{
item.Value = value;
this.Value = this.Value.AddSeconds(value - this.Value.Second);
}
break;
}
item.Text = Value.ToString(item.Format);
if (paint)
{
this.Invalidate();
}
}
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnMouseDown(MouseEventArgs e)
{
bool have = false;
for (int i = 0; i < list.Count; i++)
{
if (list[i].Rect.Contains(e.Location))
{
if(SelectedIndex!=i)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
ChangedData(list[SelectedIndex],Input_Text);
//list[SelectedIndex].
}
}
SelectedIndex = i;
have = true;
break;
}
}
if(!have)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
ChangedData(list[SelectedIndex], Input_Text);
}
SelectedIndex = -1;
Input_Text = "";
}
this.Invalidate();
base.OnMouseDown(e);
}
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnPreviewKeyDown(PreviewKeyDownEventArgs e)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
var item = list[SelectedIndex];
if (item.Editable)
{
if (e.KeyCode == Keys.Up)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
if (Input_Text.Length == 0) { Input_Text = item.Value.ToString(); }
var value = Input_Text.ToInt();
value--;
if (value < 0) { value = 0; }
Input_Text = value.ToString();
this.Invalidate();
}
}
else if (e.KeyCode == Keys.Down)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
if (Input_Text.Length == 0) { Input_Text = item.Value.ToString(); }
var value = Input_Text.ToInt();
value++;
if (value < 0) { value = 0; }
Input_Text = value.ToString();
this.Invalidate();
}
}
}
//this.Invalidate();
}
//base.OnPreviewKeyDown(e);
}
private string Input_Text { get; set; } = "";
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnKeyDown(KeyEventArgs e)
{
if(SelectedIndex>=0 && SelectedIndex<list.Count)
{
var item = list[SelectedIndex];
if (item.Editable)
{
if (e.KeyCode >= Keys.D0 && e.KeyCode <= Keys.D9)
{
// 数字键被按下,允许输入
Input_Text += (char)e.KeyValue;
}
else if (e.KeyCode >= Keys.NumPad0 && e.KeyCode <= Keys.NumPad9)
{
// 数字小键盘的按键被按下,允许输入
Input_Text += e.KeyCode- Keys.NumPad0;
}
else if(e.KeyCode== Keys.Enter)
{
if (SelectedIndex >= 0 && SelectedIndex < list.Count)
{
ChangedData(list[SelectedIndex], Input_Text);
}
}
else
{
Input_Text = "";
}
}
else
{
Input_Text = "";
}
this.Invalidate();
}
base.OnKeyDown(e);
}
private List<DateItem> list=new List<DateItem>();
/// <summary>
///
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
//e.Graphics.DrawString()
StringFormat stringFormat = new StringFormat();
stringFormat.LineAlignment = StringAlignment.Center;
stringFormat.Alignment = StringAlignment.Center;
stringFormat.Trimming = StringTrimming.None;
stringFormat.FormatFlags = StringFormatFlags.NoWrap | StringFormatFlags.FitBlackBox | StringFormatFlags.LineLimit;
var aa = StringFormat.GenericTypographic;
int num;
list.Clear();
var start_normal_pos = -1;
GraphicsPath graphicsPath = new GraphicsPath();
for (int i = 0; i < dateFormat.Length; i += num)
{
var c = dateFormat[i];
num = ParseRepeatPattern(dateFormat, i, c);
var cc = "".PadRight(num, c);
var isFormat = false;
switch (c)
{
case 'g':
case 'h':
case 'H':
case 'm':
case 's':
case 'F':
case 'f':
case 't':
case 'd':
case 'M':
case 'y':
case 'z':
case 'K':
case ':':
case '/':
case '"':
case '\'':
case '%':
case '\\':
if (start_normal_pos >= 0)
{
list.Add(new DateItem()
{
Format = "",
Text = dateFormat.Substring(start_normal_pos, i - start_normal_pos)
});
start_normal_pos = -1;
}
isFormat = true;
break;
default:
isFormat = false;
if (start_normal_pos == -1)
{
start_normal_pos = i;
}
break;
}
if (start_normal_pos >= 0)
{
continue;
}
var Editable = false;
if(cc == "yyyyy" || cc == "yyyy" || cc == "yyy" || cc=="yy" ||cc=="y")
{ Editable = true; }
else if (cc == "MM" || cc == "M" || cc == "dd" || cc == "d")
{ Editable = true; }
else if (cc == "HH" || cc == "H" || cc == "hh" || cc == "h" || cc == "mm" || cc == "m")
{ Editable = true; }
else if (cc == "ss" || cc == "s")
{ Editable = true; }
list.Add(new DateItem()
{
Format = isFormat ? cc : "",
Editable= Editable,
Text = isFormat ? Value.ToString(cc) : cc,
Value= isFormat?Value.ToString(cc).ToInt():0
});
}
if (start_normal_pos >= 0)
{
list.Add(new DateItem()
{
Format = "",
Text = dateFormat.Substring(start_normal_pos)
});
start_normal_pos = -1;
}
float pos = 0;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
for (int i = 0; i < list.Count; i++)
{
var item=list[i];
var txt_size= e.Graphics.MeasureString(item.Text, base.Font);
var rect = new RectangleF(pos, 0, txt_size.Width, Height);
item.Rect = rect;
pos += txt_size.Width;
if (SelectedIndex == i && item.Editable)
{
e.Graphics.FillRectangle(Brushes.BlueViolet, rect);
//graphicsPath.AddString(Input_Text.Length > 0 ? Input_Text : item.Text, base.Font.FontFamily, base.Font.Style.ToInt(), base.Font.Size, rect, stringFormat);
e.Graphics.DrawString(Input_Text.Length > 0 ? Input_Text : item.Text, base.Font, new SolidBrush(Color.White), rect, stringFormat);
}
else
{
//if (!item.Editable)
//{
// rect.Offset(0, (Height - txt_size.Height) / 2);
// rect.Height = txt_size.Height+2;
//}
e.Graphics.DrawString(item.Text, base.Font, new SolidBrush(base.ForeColor), rect, stringFormat);
}
}
base.OnPaint(e);
}
class DateItem
{
/// <summary>
/// 文本区域
/// </summary>
public RectangleF Rect { get; set; } = RectangleF.Empty;
/// <summary>
/// 是否可编辑
/// </summary>
public bool Editable { get; set; } = false;
public int Value { get; set; } = 0;
/// <summary>
/// 显示的文本
/// </summary>
public string Text { get; set; } = "";
/// <summary>
/// 格式化字符串
/// </summary>
public string Format { get; set; } = "";
}
}
}