### 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。
442 lines
16 KiB
C#
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; } = "";
|
|
}
|
|
}
|
|
}
|