🧙 修复 Collapse Button 无法隐藏的问题、修复 Table.Cell 编辑模式不退出的问题、Alert 新增 IconSvg自定义图标 和 CloseIcon并响应CloseChanged事件

This commit is contained in:
jesse
2025-10-09 03:36:58 +00:00
committed by Tom
parent a9c596c8b0
commit 50fdf1dcb9
6 changed files with 201 additions and 21 deletions

View File

@@ -28,6 +28,19 @@ namespace Demo.Controls
{
form = _form;
InitializeComponent();
alert1.CloseIcon = true;
alert1.CloseChanged += Alert1_CloseChanged;
alert11.CloseIcon = true;
alert11.CloseChanged += Alert1_CloseChanged;
alert11.IconRatio = 2f;
alert11.IconSvg = "UserSwitchOutlined";
}
private bool Alert1_CloseChanged(object sender, System.EventArgs e)
{
AntdUI.Notification.open(form,(sender as AntdUI.Alert).TextTitle, "Close Button Clicked", AntdUI.TAlignFrom.Top);
return false;
}
}
}

View File

@@ -35,6 +35,10 @@ namespace AntdUI
[Designer(typeof(IControlDesigner))]
public class Alert : IControl, IEventListener
{
public Alert()
{
hover_close = new ITaskOpacity(nameof(AntdUI.Alert), this);
}
#region
int radius = 6;
@@ -230,6 +234,90 @@ namespace AntdUI
loopSpeed = value;
}
}
#region
bool closeIcon = false;
/// <summary>
/// 是否显示关闭图标
/// </summary>
[Description("是否显示关闭图标"), Category("行为"), DefaultValue(false)]
public bool CloseIcon
{
get => closeIcon;
set
{
if (closeIcon == value) return;
closeIcon = value;
Invalidate();
OnPropertyChanged(nameof(CloseIcon));
}
}
float icongap = .25F;
/// <summary>
/// 图标与文字间距比例
/// </summary>
[Description("图标与文字间距比例"), Category("外观"), DefaultValue(.25F)]
public float IconGap
{
get => icongap;
set
{
if (icongap == value) return;
icongap = value;
Invalidate();
OnPropertyChanged(nameof(IconGap));
}
}
float iconratio = 1F;
/// <summary>
/// 图标比例
/// </summary>
[Description("图标比例"), Category("外观"), DefaultValue(1F)]
public float IconRatio
{
get => iconratio;
set
{
if (iconratio == value) return;
iconratio = value;
Invalidate();
OnPropertyChanged(nameof(IconRatio));
}
}
string? iconSvg;
/// <summary>
/// 自定义图标SVG
/// </summary>
[Description("自定义图标SVG"), Category("外观"), DefaultValue(null)]
public string? IconSvg
{
get => iconSvg;
set
{
if (iconSvg == value) return;
iconSvg = value;
Invalidate();
OnPropertyChanged(nameof(IconSvg));
}
}
public Alert SetIcon(string? value)
{
iconSvg = value;
Invalidate();
return this;
}
/// <summary>
/// 是否包含自定义图标
/// </summary>
public bool HasIcon => iconSvg != null;
#endregion
#region
@@ -289,7 +377,42 @@ namespace AntdUI
public override Rectangle DisplayRectangle => ClientRectangle.PaddingRect(Padding, borWidth / 2F * Config.Dpi);
#endregion
#region
/// <summary>
/// Close时发生
/// </summary>
[Description("Close时发生"), Category("行为")]
public event RBoolEventHandler? CloseChanged;
#endregion
#region
ITaskOpacity hover_close;
RectangleF rect_close;
protected override void OnMouseClick(MouseEventArgs e)
{
if (e.Button == MouseButtons.Left && closeIcon && rect_close.Contains(e.X, e.Y))
{
bool isclose = false;
if (CloseChanged == null || CloseChanged(this, EventArgs.Empty)) isclose = true;
if (isclose) Dispose();
return;
}
base.OnMouseClick(e);
}
protected override void OnMouseMove(MouseEventArgs e)
{
if (closeIcon)
{
hover_close.MaxValue = Colour.Text.Get(nameof(AntdUI.Tag), ColorScheme).A - Colour.TextQuaternary.Get(nameof(AntdUI.Tag), ColorScheme).A;
hover_close.Switch = rect_close.Contains(e.X, e.Y);
SetCursor(hover_close.Switch);
}
else SetCursor(false);
base.OnMouseMove(e);
}
#endregion
#region
protected override void OnDraw(DrawEventArgs e)
@@ -297,7 +420,8 @@ namespace AntdUI
var rect = DisplayRectangle;
var g = e.Canvas;
bool hasText = string.IsNullOrEmpty(Text);
if (icon == TType.None)
bool hasIcon = HasIcon;
if (icon == TType.None && !hasIcon)
{
if (loop)
{
@@ -377,11 +501,17 @@ namespace AntdUI
if (font_size == null && !hasText) font_size = g.MeasureText(Text, Font);
if (font_size.HasValue)
{
int icon_size = (int)(sizeT.Height * .86F), gap = (int)(icon_size * .4F);
int icon_size = (int)(sizeT.Height * iconratio), gap = (int)(icon_size * icongap);
var rect_icon = new Rectangle(gap, rect.Y + (rect.Height - icon_size) / 2, icon_size, icon_size);
PaintText(g, rect, rect_icon, font_size.Value, color, back, _radius);
g.ResetClip();
g.PaintIcons(icon, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
if (hasIcon)
{
IconInfo ci = new IconInfo(IconSvg, bor_color);
g.PaintIcons(ci, rect_icon);
}
else
g.PaintIcons(icon, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
}
}
else
@@ -393,29 +523,45 @@ namespace AntdUI
}
if (string.IsNullOrEmpty(TextTitle))
{
int icon_size = (int)(sizeT.Height * .86F), gap = (int)(icon_size * .4F);
int icon_size = (int)(sizeT.Height * iconratio), gap = (int)(icon_size * icongap);
var rect_icon = new Rectangle(rect.X + gap, rect.Y + (rect.Height - icon_size) / 2, icon_size, icon_size);
g.PaintIcons(icon, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
if (hasIcon)
{
IconInfo ci = new IconInfo(IconSvg, bor_color);
g.PaintIcons(ci, rect_icon);
}
else
g.PaintIcons(icon, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
var rect_txt = new Rectangle(rect_icon.X + rect_icon.Width + gap, rect.Y, rect.Width - (rect_icon.Width + gap * 3), rect.Height);
g.DrawText(Text, Font, color, rect_txt, sf);
if (closeIcon) PaintCloseIcon(g, rect, color);
}
else
{
using (var font_title = new Font(Font.FontFamily, Font.Size * 1.14F, Font.Style))
{
int icon_size = (int)(sizeT.Height * 1.2F), gap = (int)(icon_size * .5F);
int icon_size = (int)(sizeT.Height * (iconratio + 0.2F)), gap = (int)(icon_size * (icongap + 0.1F));
var rect_icon = new Rectangle(rect.X + gap, rect.Y + gap, icon_size, icon_size);
g.PaintIcons(icon, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
if (hasIcon)
{
IconInfo ci = new IconInfo(IconSvg, bor_color);
g.PaintIcons(ci, rect_icon);
}
else
g.PaintIcons(icon, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
using (var brush = new SolidBrush(color))
{
var rect_txt = new Rectangle(rect_icon.X + rect_icon.Width + icon_size / 2, rect_icon.Y, rect.Width - (rect_icon.Width + gap * 3), rect_icon.Height);
g.DrawText(TextTitle, font_title, brush, rect_txt, sf);
var desc_y = rect_txt.Bottom + (int)(icon_size * .2F);
var desc_y = rect_txt.Bottom + (int)(icon_size * .1F);
var rect_txt_desc = new Rectangle(rect_txt.X, desc_y, rect_txt.Width, rect.Height - (desc_y + gap));
g.DrawText(Text, Font, brush, rect_txt_desc, sEllipsis);
if (closeIcon) PaintCloseIcon(g, rect, color);
}
}
}
@@ -426,6 +572,16 @@ namespace AntdUI
base.OnDraw(e);
}
private void PaintCloseIcon(Canvas g, Rectangle rect_read, Color color)
{
int size = (int)((rect_read.Height > 48 ? 48 : rect_read.Height) * .4F);
int gap = (int)(4 * Config.Dpi);
var rect_arrow = new Rectangle(rect_read.X + (rect_read.Width - size - gap), rect_read.Y + gap, size, size);
rect_close = rect_arrow;
if (hover_close.Animation) g.PaintIconClose(rect_arrow, Helper.ToColor(hover_close.Value + Colour.TextQuaternary.Get(nameof(AntdUI.Tag), ColorScheme).A, Colour.Text.Get(nameof(AntdUI.Tag), ColorScheme)));
else if (hover_close.Switch) g.PaintIconClose(rect_arrow, Colour.Text.Get(nameof(AntdUI.Tag), ColorScheme));
else g.PaintIconClose(rect_arrow, Colour.TextQuaternary.Get(nameof(AntdUI.Tag), ColorScheme));
}
#region
readonly StringFormat sEllipsis = Helper.SF_Ellipsis(tb: StringAlignment.Near, lr: StringAlignment.Near);
@@ -503,10 +659,10 @@ namespace AntdUI
using (var brush_fore = new SolidBrush(fore))
{
var rect_txt = new Rectangle(rect.X - val, rect.Y, size.Width, rect.Height);
g.SetClip(new Rectangle(rect.X, rect_txt.Y + ((rect.Height - size.Height) / 2), rect.Width, size.Height));
g.DrawText(Text, Font, brush_fore, rect_txt, sc);
if (closeIcon) PaintCloseIcon(g,rect_txt,fore);
if (LoopInfinite && rect.Width > size.Width)
{
var maxw = rect.Width + rect_txt.Width / 2;

View File

@@ -919,12 +919,6 @@ namespace AntdUI
}
}
internal override bool Show
{
get => Visible;
set => base.Show = Visible = value;
}
bool switchMode = false;
//[Obsolete("请使用EditType")]
[Browsable(false)]

View File

@@ -395,10 +395,19 @@ namespace AntdUI
if (AddEditInput(input, old, call))
{
input.KeyPress += InputEdit_KeyPress;
input.LostFocus += Input_LostFocus;
input.Focus();
}
}
private void Input_LostFocus(object? sender, EventArgs e)
{
if (sender is Input edit)
{
InputEdit_KeyPress(sender, new KeyPressEventArgs((char)13));
}
}
void ShowSelect(Select select, Action<bool, object?> call)
{
var old = select.SelectedValue;
@@ -415,9 +424,7 @@ namespace AntdUI
{
if (sender is Select select)
{
select.LostFocus -= Select_LostFocus;
EditModeClose();
Select_ClosedItem(sender, new ObjectNEventArgs(select.SelectedValue));
}
}
@@ -425,8 +432,9 @@ namespace AntdUI
{
if (sender is Select select)
{
select.SelectedValueChanged -= InputEdit_SelectedValueChanged;
select.ClosedItem -= Select_ClosedItem;
select.LostFocus -= Select_LostFocus;
EditModeClose();
}
}
@@ -439,6 +447,7 @@ namespace AntdUI
{
e.Handled = true;
input.KeyPress -= InputEdit_KeyPress;
input.LostFocus -= Input_LostFocus;
if (_editControls.TryGetValue(input, out var obj))
{
if (obj[1] is Action<bool, string> call)
@@ -456,6 +465,8 @@ namespace AntdUI
if (sender is Select select)
{
select.SelectedValueChanged -= InputEdit_SelectedValueChanged;
select.ClosedItem -= Select_ClosedItem;
select.LostFocus -= Select_LostFocus;
if (_editControls.TryGetValue(select, out var obj))
{
if (obj[1] is Action<bool, object?> call)

View File

@@ -127,6 +127,7 @@ namespace AntdUI
Bitmap? bmp_tmp;
void SetAnimateValue(byte _alpha, bool isrint = false)
{
if (form == null || form.IsDisposed) return;
if (isrint)
{
form.alpha = _alpha;

View File

@@ -202,7 +202,12 @@ namespace AntdUI
}
}
}
return new Bitmap(temp);
try
{
if (temp == null) return null;
return new Bitmap(temp);
}
catch { return null; }
}
protected override void OnMouseClick(MouseEventArgs e)