🏳️‍🌈 Spin 新增 Indicator 自定义加载指示符、修复 Spin 隐藏后依旧显示、Table 编辑模式回滚失去焦点关闭、Table 修复 点击空白处退出编辑模式、Select 新增 EnterDropDown 属性 用于部分场景中是否允许回车键触发下拉框、修复 Collapse Button 无法隐藏

This commit is contained in:
Tom
2025-10-10 15:08:03 +08:00
parent 50fdf1dcb9
commit 70c75b5baa
27 changed files with 1130 additions and 367 deletions

View File

@@ -28,19 +28,6 @@ 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

@@ -0,0 +1,230 @@
using System.Drawing;
namespace Demo.Controls
{
partial class HyperlinkLabel
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
header1 = new AntdUI.PageHeader();
panel1 = new System.Windows.Forms.Panel();
hyperlinkLabel5 = new AntdUI.HyperlinkLabel();
divider5 = new AntdUI.Divider();
hyperlinkLabel4 = new AntdUI.HyperlinkLabel();
divider4 = new AntdUI.Divider();
hyperlinkLabel3 = new AntdUI.HyperlinkLabel();
divider3 = new AntdUI.Divider();
hyperlinkLabel2 = new AntdUI.HyperlinkLabel();
divider2 = new AntdUI.Divider();
hyperlinkLabel1 = new AntdUI.HyperlinkLabel();
divider1 = new AntdUI.Divider();
panel1.SuspendLayout();
SuspendLayout();
//
// header1
//
header1.Description = "超链接文本 <a>";
header1.Dock = System.Windows.Forms.DockStyle.Top;
header1.Font = new Font("Microsoft YaHei UI", 12F);
header1.LocalizationDescription = "HyperlinkLabel.Description";
header1.LocalizationText = "HyperlinkLabel.Text";
header1.Location = new Point(0, 0);
header1.Name = "header1";
header1.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
header1.Size = new Size(592, 74);
header1.TabIndex = 1;
header1.Text = "HyperlinkLabel 超链接文本";
header1.UseTitleFont = true;
//
// panel1
//
panel1.AutoScroll = true;
panel1.Controls.Add(hyperlinkLabel5);
panel1.Controls.Add(divider5);
panel1.Controls.Add(hyperlinkLabel4);
panel1.Controls.Add(divider4);
panel1.Controls.Add(hyperlinkLabel3);
panel1.Controls.Add(divider3);
panel1.Controls.Add(hyperlinkLabel2);
panel1.Controls.Add(divider2);
panel1.Controls.Add(hyperlinkLabel1);
panel1.Controls.Add(divider1);
panel1.Dock = System.Windows.Forms.DockStyle.Fill;
panel1.Location = new Point(0, 74);
panel1.Name = "panel1";
panel1.Size = new Size(592, 402);
panel1.TabIndex = 2;
//
// hyperlinkLabel5
//
hyperlinkLabel5.Dock = System.Windows.Forms.DockStyle.Top;
hyperlinkLabel5.Location = new Point(0, 260);
hyperlinkLabel5.Name = "hyperlinkLabel5";
hyperlinkLabel5.Padding = new System.Windows.Forms.Padding(30, 0, 30, 0);
hyperlinkLabel5.Size = new Size(592, 30);
hyperlinkLabel5.TabIndex = 5;
hyperlinkLabel5.Text = "多个链接: <a href=one>链接1</a> 和 <a href=two>链接2</a>";
hyperlinkLabel5.LinkClicked += hyperlinkLabel_LinkClicked;
//
// divider5
//
divider5.Dock = System.Windows.Forms.DockStyle.Top;
divider5.Font = new Font("Microsoft YaHei UI", 10F);
divider5.LocalizationText = "HyperlinkLabel.{id}";
divider5.Location = new Point(0, 232);
divider5.Name = "divider5";
divider5.Orientation = AntdUI.TOrientation.Left;
divider5.Size = new Size(592, 28);
divider5.TabIndex = 0;
divider5.TabStop = false;
divider5.Text = "多个链接";
//
// hyperlinkLabel4
//
hyperlinkLabel4.Dock = System.Windows.Forms.DockStyle.Top;
hyperlinkLabel4.Location = new Point(0, 202);
hyperlinkLabel4.Name = "hyperlinkLabel4";
hyperlinkLabel4.Padding = new System.Windows.Forms.Padding(30, 0, 30, 0);
hyperlinkLabel4.Size = new Size(592, 30);
hyperlinkLabel4.TabIndex = 4;
hyperlinkLabel4.Text = "自定义样式 <a href=none>链接</a>";
hyperlinkLabel4.LinkClicked += hyperlinkLabel_LinkClicked;
//
// divider4
//
divider4.Dock = System.Windows.Forms.DockStyle.Top;
divider4.Font = new Font("Microsoft YaHei UI", 10F);
divider4.LocalizationText = "HyperlinkLabel.{id}";
divider4.Location = new Point(0, 174);
divider4.Name = "divider4";
divider4.Orientation = AntdUI.TOrientation.Left;
divider4.Size = new Size(592, 28);
divider4.TabIndex = 0;
divider4.TabStop = false;
divider4.Text = "自定义样式";
//
// hyperlinkLabel3
//
hyperlinkLabel3.Badge = "New";
hyperlinkLabel3.BadgeAlign = AntdUI.TAlign.RT;
hyperlinkLabel3.Dock = System.Windows.Forms.DockStyle.Top;
hyperlinkLabel3.Location = new Point(0, 144);
hyperlinkLabel3.Name = "hyperlinkLabel3";
hyperlinkLabel3.Padding = new System.Windows.Forms.Padding(30, 0, 30, 0);
hyperlinkLabel3.Size = new Size(592, 30);
hyperlinkLabel3.TabIndex = 3;
hyperlinkLabel3.Text = "带徽章的 <a href=none>超链接</a>";
hyperlinkLabel3.LinkClicked += hyperlinkLabel_LinkClicked;
//
// divider3
//
divider3.Dock = System.Windows.Forms.DockStyle.Top;
divider3.Font = new Font("Microsoft YaHei UI", 10F);
divider3.LocalizationText = "HyperlinkLabel.{id}";
divider3.Location = new Point(0, 116);
divider3.Name = "divider3";
divider3.Orientation = AntdUI.TOrientation.Left;
divider3.Size = new Size(592, 28);
divider3.TabIndex = 0;
divider3.TabStop = false;
divider3.Text = "带徽章的";
//
// hyperlinkLabel2
//
hyperlinkLabel2.Dock = System.Windows.Forms.DockStyle.Top;
hyperlinkLabel2.Location = new Point(0, 86);
hyperlinkLabel2.Name = "hyperlinkLabel2";
hyperlinkLabel2.Size = new Size(592, 30);
hyperlinkLabel2.TabIndex = 2;
hyperlinkLabel2.Text = "居中对齐的 <a href=none>超链接</a>";
hyperlinkLabel2.TextAlign = ContentAlignment.MiddleCenter;
hyperlinkLabel2.LinkClicked += hyperlinkLabel_LinkClicked;
//
// divider2
//
divider2.Dock = System.Windows.Forms.DockStyle.Top;
divider2.Font = new Font("Microsoft YaHei UI", 10F);
divider2.LocalizationText = "HyperlinkLabel.{id}";
divider2.Location = new Point(0, 58);
divider2.Name = "divider2";
divider2.Orientation = AntdUI.TOrientation.Left;
divider2.Size = new Size(592, 28);
divider2.TabIndex = 0;
divider2.TabStop = false;
divider2.Text = "居中对齐";
//
// hyperlinkLabel1
//
hyperlinkLabel1.Dock = System.Windows.Forms.DockStyle.Top;
hyperlinkLabel1.Location = new Point(0, 28);
hyperlinkLabel1.Name = "hyperlinkLabel1";
hyperlinkLabel1.Padding = new System.Windows.Forms.Padding(30, 0, 30, 0);
hyperlinkLabel1.Size = new Size(592, 30);
hyperlinkLabel1.TabIndex = 1;
hyperlinkLabel1.Text = "这是一个 <a href=none>超链接</a> 测试";
hyperlinkLabel1.LinkClicked += hyperlinkLabel_LinkClicked;
//
// divider1
//
divider1.Dock = System.Windows.Forms.DockStyle.Top;
divider1.Font = new Font("Microsoft YaHei UI", 10F);
divider1.LocalizationText = "HyperlinkLabel.{id}";
divider1.Location = new Point(0, 0);
divider1.Name = "divider1";
divider1.Orientation = AntdUI.TOrientation.Left;
divider1.Size = new Size(592, 28);
divider1.TabIndex = 0;
divider1.TabStop = false;
divider1.Text = "常规";
//
// HyperlinkLabel
//
Controls.Add(panel1);
Controls.Add(header1);
Name = "HyperlinkLabel";
Size = new Size(592, 476);
panel1.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private AntdUI.PageHeader header1;
private System.Windows.Forms.Panel panel1;
private AntdUI.HyperlinkLabel hyperlinkLabel1;
private AntdUI.HyperlinkLabel hyperlinkLabel2;
private AntdUI.HyperlinkLabel hyperlinkLabel3;
private AntdUI.HyperlinkLabel hyperlinkLabel4;
private AntdUI.HyperlinkLabel hyperlinkLabel5;
private AntdUI.Divider divider1;
private AntdUI.Divider divider2;
private AntdUI.Divider divider5;
private AntdUI.Divider divider4;
private AntdUI.Divider divider3;
}
}

View File

@@ -0,0 +1,53 @@
// COPYRIGHT (C) Tom. ALL RIGHTS RESERVED.
// THE AntdUI PROJECT IS AN WINFORM LIBRARY LICENSED UNDER THE Apache-2.0 License.
// LICENSED UNDER THE Apache License, VERSION 2.0 (THE "License")
// YOU MAY NOT USE THIS FILE EXCEPT IN COMPLIANCE WITH THE License.
// YOU MAY OBTAIN A COPY OF THE LICENSE AT
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING, SOFTWARE
// DISTRIBUTED UNDER THE LICENSE IS DISTRIBUTED ON AN "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
// SEE THE LICENSE FOR THE SPECIFIC LANGUAGE GOVERNING PERMISSIONS AND
// LIMITATIONS UNDER THE License.
// GITCODE: https://gitcode.com/AntdUI/AntdUI
// GITEE: https://gitee.com/AntdUI/AntdUI
// GITHUB: https://github.com/AntdUI/AntdUI
// CSDN: https://blog.csdn.net/v_132
// QQ: 17379620
using System.Windows.Forms;
namespace Demo.Controls
{
public partial class HyperlinkLabel : UserControl
{
Form form;
public HyperlinkLabel(Form _form)
{
form = _form;
InitializeComponent();
// 测试样式
hyperlinkLabel4.NormalStyle = new AntdUI.HyperlinkLabel.LinkAppearance
{
LinkColor = AntdUI.Style.Db.Error,
UnderlineThickness = 1
};
hyperlinkLabel4.HoverStyle = new AntdUI.HyperlinkLabel.LinkAppearance
{
LinkColor = AntdUI.Style.Db.ErrorActive,
UnderlineThickness = 2
};
}
private void hyperlinkLabel_LinkClicked(object sender, AntdUI.HyperlinkLabel.LinkClickedEventArgs e)
{
if (sender == hyperlinkLabel2) AntdUI.Message.success(FindForm(), "居中链接被点击: " + e.Text);
else if (sender == hyperlinkLabel3) AntdUI.Message.success(FindForm(), "带徽章的链接被点击: " + e.Text);
else AntdUI.Message.success(form, "点击了: " + e.Text);
}
}
}

View File

@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View File

@@ -48,6 +48,7 @@ namespace Demo.Controls
{
header1 = new AntdUI.PageHeader();
panel1 = new System.Windows.Forms.Panel();
divider4 = new AntdUI.Divider();
panel4 = new System.Windows.Forms.Panel();
select8 = new AntdUI.Select();
selectMultiple1 = new AntdUI.SelectMultiple();
@@ -67,6 +68,7 @@ namespace Demo.Controls
select5 = new AntdUI.Select();
select1 = new AntdUI.Select();
divider1 = new AntdUI.Divider();
select9 = new AntdUI.Select();
panel1.SuspendLayout();
panel4.SuspendLayout();
panel3.SuspendLayout();
@@ -93,6 +95,8 @@ namespace Demo.Controls
// panel1
//
panel1.AutoScroll = true;
panel1.Controls.Add(select9);
panel1.Controls.Add(divider4);
panel1.Controls.Add(panel4);
panel1.Controls.Add(divider3);
panel1.Controls.Add(panel3);
@@ -105,6 +109,19 @@ namespace Demo.Controls
panel1.Size = new Size(555, 480);
panel1.TabIndex = 6;
//
// divider4
//
divider4.Dock = DockStyle.Top;
divider4.Font = new Font("Microsoft YaHei UI", 10F);
divider4.LocalizationText = "Select.{id}";
divider4.Location = new Point(0, 397);
divider4.Name = "divider4";
divider4.Orientation = AntdUI.TOrientation.Left;
divider4.Size = new Size(555, 28);
divider4.TabIndex = 6;
divider4.TabStop = false;
divider4.Text = "回车下拉框控制";
//
// panel4
//
panel4.Controls.Add(select8);
@@ -329,6 +346,22 @@ namespace Demo.Controls
divider1.TabStop = false;
divider1.Text = "常规";
//
// select9
//
select9.DropDownArrow = true;
select9.EnterDropDown = false;
select9.Items.AddRange(new object[] { "A", "B", "C", "D", "E", "F", "G" });
select9.List = true;
select9.ListAutoWidth = true;
select9.LocalizationPlaceholderText = "Select.{id}";
select9.Location = new Point(18, 431);
select9.Margin = new Padding(2, 3, 2, 3);
select9.Name = "select9";
select9.PlaceholderText = "测试数据";
select9.Placement = AntdUI.TAlignFrom.TR;
select9.Size = new Size(120, 41);
select9.TabIndex = 7;
//
// Select
//
Controls.Add(panel1);
@@ -368,5 +401,7 @@ namespace Demo.Controls
private AntdUI.Button button4;
private AntdUI.Select select8;
private AntdUI.SelectMultiple selectMultiple1;
private AntdUI.Divider divider4;
private AntdUI.Select select9;
}
}

View File

@@ -39,7 +39,7 @@ namespace Demo.Controls
}
} }
},
new AntdUI.SelectItem( "<22>Ӳ˵<D3B2>2")
new AntdUI.SelectItem("<22>Ӳ˵<D3B2>2")
}
},
new AntdUI.SelectItem("two"){ Sub=new List<object>{ "five menu item", "six six six menu item"} },

View File

@@ -24,7 +24,7 @@ namespace Demo.Controls
{
public partial class Watermark : UserControl
{
private Form form;
Form form;
public Watermark(Form _form)
{

View File

@@ -830,6 +830,22 @@ namespace Demo
case "Chart.Description":
return "Visual chart library.";
//HyperlinkLabel ----------------------------
case "HyperlinkLabel.Text":
return "HyperlinkLabel";
case "HyperlinkLabel.Description":
return "Hyperlink text<a>";
case "HyperlinkLabel.divider1":
return "Basic";
case "HyperlinkLabel.divider2":
return "Center alignment";
case "HyperlinkLabel.divider3":
return "Link with badge";
case "HyperlinkLabel.divider4":
return "Custom Style";
case "HyperlinkLabel.divider5":
return "Multiple links";
#endregion
case "Loading":

Binary file not shown.

View File

@@ -222,6 +222,15 @@ namespace Demo {
}
}
/// <summary>
/// 查找类似 &lt;svg width=&quot;265px&quot; height=&quot;219px&quot; viewBox=&quot;0 0 265 219&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;defs&gt;&lt;rect id=&quot;path-1&quot; x=&quot;6&quot; y=&quot;6.5&quot; width=&quot;137&quot; height=&quot;90&quot;&gt;&lt;/rect&gt;&lt;filter x=&quot;-74.5%&quot; y=&quot;-100.0%&quot; width=&quot;248.9%&quot; height=&quot;326.7%&quot; filterUnits=&quot;objectBoundingBox&quot; id=&quot;filter-2&quot;&gt;&lt;feMorphology radius=&quot;8&quot; operator=&quot;dilate&quot; in=&quot;SourceAlpha&quot; result=&quot;shadowSpreadOuter1&quot;&gt;&lt;/feMorphology&gt;&lt;feOffset dx=&quot;0&quot; dy=&quot;12&quot; in=&quot;shadowSpreadOuter1&quot; result=&quot;shadowOffsetOuter1&quot;&gt;&lt;/feOffset&gt;&lt;feGaussianBlur stdDeviation=&quot;24&quot; in=&quot;shadowO [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string HyperlinkLabel {
get {
return ResourceManager.GetString("HyperlinkLabel", resourceCulture);
}
}
/// <summary>
/// 查找类似 &lt;svg width=&quot;112px&quot; height=&quot;32px&quot; viewBox=&quot;0 0 112 32&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;g id=&quot;组件骨架图更新&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;g id=&quot;🎉-5.0-新版---黑&quot; transform=&quot;translate(-562.000000, -463.000000)&quot;&gt;&lt;g id=&quot;Icon&quot; transform=&quot;translate(562.000000, 463.000000)&quot;&gt;&lt;g id=&quot;smile-fill&quot;&gt;&lt;rect id=&quot;矩形&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot; opacity=&quot;0&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;32&quot; height=&quot;32&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M16,2 C8.26875,2 2,8.26875 2,16 C2,23.73125 8.26875,30 16,30 C23.73125,30 30 [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>

View File

@@ -273,4 +273,7 @@
<data name="Chart" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" width="140" height="140"&gt;&lt;path d="M428.501333 64a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128A64 64 0 0 1 64 170.666667V128A64 64 0 0 1 128 64h300.501333z" fill="#29C287"&gt;&lt;/path&gt;&lt;path d="M896 305.92a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128a64 64 0 0 1-64-64v-42.666667A64 64 0 0 1 128 305.92h768z" fill="#706EE7"&gt;&lt;/path&gt;&lt;path d="M584.362667 547.413333a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128a64 64 0 0 1-64-64v-42.666667a64 64 0 0 1 64-64h456.362667z" fill="#29C287"&gt;&lt;/path&gt;&lt;path d="M311.637333 789.333333a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128A64 64 0 0 1 64 896v-42.666667A64 64 0 0 1 128 789.333333h183.637333z" fill="#706EE7"&gt;&lt;/path&gt;&lt;/svg&gt;</value>
</data>
<data name="HyperlinkLabel" xml:space="preserve">
<value>&lt;svg width="265px" height="219px" viewBox="0 0 265 219" xmlns:xlink="http://www.w3.org/1999/xlink"&gt;&lt;defs&gt;&lt;rect id="path-1" x="6" y="6.5" width="137" height="90"&gt;&lt;/rect&gt;&lt;filter x="-74.5%" y="-100.0%" width="248.9%" height="326.7%" filterUnits="objectBoundingBox" id="filter-2"&gt;&lt;feMorphology radius="8" operator="dilate" in="SourceAlpha" result="shadowSpreadOuter1"&gt;&lt;/feMorphology&gt;&lt;feOffset dx="0" dy="12" in="shadowSpreadOuter1" result="shadowOffsetOuter1"&gt;&lt;/feOffset&gt;&lt;feGaussianBlur stdDeviation="24" in="shadowOffsetOuter1" result="shadowBlurOuter1"&gt;&lt;/feGaussianBlur&gt;&lt;feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.09 0" type="matrix" in="shadowBlurOuter1" result="shadowMatrixOuter1"&gt;&lt;/feColorMatrix&gt;&lt;feOffset dx="0" dy="9" in="SourceAlpha" result="shadowOffsetOuter2"&gt;&lt;/feOffset&gt;&lt;feGaussianBlur stdDeviation="14" in="shadowOffsetOuter2" result="shadowBlurOuter2"&gt;&lt;/feGaussianBlur&gt;&lt;feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.15 0" type="matrix" in="shadowBlurOuter2" result="shadowMatrixOuter2"&gt;&lt;/feColorMatrix&gt;&lt;feMorphology radius="4" operator="erode" in="SourceAlpha" result="shadowSpreadOuter3"&gt;&lt;/feMorphology&gt;&lt;feOffset dx="0" dy="6" in="shadowSpreadOuter3" result="shadowOffsetOuter3"&gt;&lt;/feOffset&gt;&lt;feGaussianBlur stdDeviation="8" in="shadowOffsetOuter3" result="shadowBlurOuter3"&gt;&lt;/feGaussianBlur&gt;&lt;feColorMatrix values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.24 0" type="matrix" in="shadowBlurOuter3" result="shadowMatrixOuter3"&gt;&lt;/feColorMatrix&gt;&lt;feMerge&gt;&lt;feMergeNode in="shadowMatrixOuter1"&gt;&lt;/feMergeNode&gt;&lt;feMergeNode in="shadowMatrixOuter2"&gt;&lt;/feMergeNode&gt;&lt;feMergeNode in="shadowMatrixOuter3"&gt;&lt;/feMergeNode&gt;&lt;/feMerge&gt;&lt;/filter&gt;&lt;/defs&gt;&lt;g id="组件骨架图更新" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"&gt;&lt;g id="🎉-5.0-新版---黑" transform="translate(-849.000000, -381.000000)"&gt;&lt;g id="Typography" transform="translate(907.000000, 427.000000)"&gt;&lt;g id="矩形复制-90"&gt;&lt;use fill="#000" fill-opacity="1" filter="url(#filter-2)" xlink:href="#path-1"&gt;&lt;/use&gt;&lt;use fill="#1F1F1F" fill-rule="evenodd" xlink:href="#path-1"&gt;&lt;/use&gt;&lt;/g&gt;&lt;rect id="矩形" fill-opacity="0.250081949" fill="#FFFFFF" fill-rule="nonzero" x="0" y="18.5" width="150" height="1"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-89" fill-opacity="0.250081949" fill="#FFFFFF" fill-rule="nonzero" transform="translate(19.000000, 52.000000) rotate(90.000000) translate(-19.000000, -52.000000) " x="-33" y="51.5" width="104" height="1"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-91" fill-opacity="0.250081949" fill="#FFFFFF" fill-rule="nonzero" transform="translate(131.000000, 52.000000) rotate(90.000000) translate(-131.000000, -52.000000) " x="79" y="51.5" width="104" height="1"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-88" fill-opacity="0.250081949" fill="#FFFFFF" fill-rule="nonzero" x="0" y="83.5" width="150" height="1"&gt;&lt;/rect&gt;&lt;g id="Aa" transform="translate(24.000000, 18.500000)" fill="#1677FF" fill-rule="nonzero" font-family="PingFangSC-Regular, PingFang SC" font-size="48" font-weight="normal"&gt;&lt;text&gt;&lt;tspan x="0" y="51"&gt;Aa&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;rect id="矩形" fill-opacity="0.15" fill="#FFFFFF" fill-rule="nonzero" opacity="0.999255952" x="53" y="31.5" width="70" height="6"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-93" fill-opacity="0.15" fill="#FFFFFF" fill-rule="nonzero" opacity="0.999255952" x="87" y="52.5" width="36" height="6"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-94" fill-opacity="0.15" fill="#FFFFFF" fill-rule="nonzero" opacity="0.999255952" x="87" y="63.5" width="36" height="6"&gt;&lt;/rect&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;</value>
</data>
</root>

View File

@@ -222,6 +222,15 @@ namespace Demo {
}
}
/// <summary>
/// 查找类似 &lt;svg width=&quot;150px&quot; height=&quot;104px&quot; viewBox=&quot;0 0 150 104&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;g id=&quot;组件骨架图更新&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;g id=&quot;🎉-5.0-新版&quot; transform=&quot;translate(-907.000000, -427.000000)&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;g id=&quot;Typography&quot; transform=&quot;translate(907.000000, 427.000000)&quot;&gt;&lt;rect id=&quot;矩形复制-90&quot; fill=&quot;#F5F5F5&quot; x=&quot;6&quot; y=&quot;6.5&quot; width=&quot;137&quot; height=&quot;90&quot;&gt;&lt;/rect&gt;&lt;rect id=&quot;矩形&quot; fill=&quot;#E0E0E0&quot; x=&quot;0&quot; y=&quot;18.5&quot; width=&quot;150&quot; height=&quot;1&quot;&gt;&lt;/rect&gt;&lt;rect id=&quot;矩形复制-89&quot; fill=&quot;#E0E0 [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string HyperlinkLabel {
get {
return ResourceManager.GetString("HyperlinkLabel", resourceCulture);
}
}
/// <summary>
/// 查找类似 &lt;svg width=&quot;112px&quot; height=&quot;32px&quot; viewBox=&quot;0 0 112 32&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;g id=&quot;组件骨架图更新&quot; stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;g id=&quot;🎉-5.0-新版&quot; transform=&quot;translate(-562.000000, -463.000000)&quot;&gt;&lt;g id=&quot;Icon&quot; transform=&quot;translate(562.000000, 463.000000)&quot;&gt;&lt;g id=&quot;smile-fill&quot;&gt;&lt;rect id=&quot;矩形&quot; fill=&quot;#000000&quot; fill-rule=&quot;nonzero&quot; opacity=&quot;0&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;32&quot; height=&quot;32&quot;&gt;&lt;/rect&gt;&lt;path d=&quot;M16,2 C8.26875,2 2,8.26875 2,16 C2,23.73125 8.26875,30 16,30 C23.73125,30 30,23. [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>

View File

@@ -273,4 +273,7 @@
<data name="Chart" xml:space="preserve">
<value>&lt;svg viewBox="0 0 1024 1024" width="140" height="140"&gt;&lt;path d="M428.501333 64a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128A64 64 0 0 1 64 170.666667V128A64 64 0 0 1 128 64h300.501333z" fill="#29C287"&gt;&lt;/path&gt;&lt;path d="M896 305.92a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128a64 64 0 0 1-64-64v-42.666667A64 64 0 0 1 128 305.92h768z" fill="#706EE7"&gt;&lt;/path&gt;&lt;path d="M584.362667 547.413333a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128a64 64 0 0 1-64-64v-42.666667a64 64 0 0 1 64-64h456.362667z" fill="#29C287"&gt;&lt;/path&gt;&lt;path d="M311.637333 789.333333a64 64 0 0 1 64 64v42.666667a64 64 0 0 1-64 64H128A64 64 0 0 1 64 896v-42.666667A64 64 0 0 1 128 789.333333h183.637333z" fill="#706EE7"&gt;&lt;/path&gt;&lt;/svg&gt;</value>
</data>
<data name="HyperlinkLabel" xml:space="preserve">
<value>&lt;svg width="150px" height="104px" viewBox="0 0 150 104" xmlns:xlink="http://www.w3.org/1999/xlink"&gt;&lt;g id="组件骨架图更新" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd"&gt;&lt;g id="🎉-5.0-新版" transform="translate(-907.000000, -427.000000)" fill-rule="nonzero"&gt;&lt;g id="Typography" transform="translate(907.000000, 427.000000)"&gt;&lt;rect id="矩形复制-90" fill="#F5F5F5" x="6" y="6.5" width="137" height="90"&gt;&lt;/rect&gt;&lt;rect id="矩形" fill="#E0E0E0" x="0" y="18.5" width="150" height="1"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-89" fill="#E0E0E0" transform="translate(19.000000, 52.000000) rotate(90.000000) translate(-19.000000, -52.000000) " x="-33" y="51.5" width="104" height="1"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-91" fill="#E0E0E0" transform="translate(131.000000, 52.000000) rotate(90.000000) translate(-131.000000, -52.000000) " x="79" y="51.5" width="104" height="1"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-88" fill="#E0E0E0" x="0" y="83.5" width="150" height="1"&gt;&lt;/rect&gt;&lt;g id="Aa" transform="translate(24.000000, 18.500000)" fill="#1677FF" font-family="PingFangSC-Regular, PingFang SC" font-size="48" font-weight="normal"&gt;&lt;text&gt;&lt;tspan x="0" y="51"&gt;Aa&lt;/tspan&gt;&lt;/text&gt;&lt;/g&gt;&lt;rect id="矩形" fill="#F5F5F5" style="mix-blend-mode: multiply;" x="53" y="31.5" width="70" height="6"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-92" fill="#F5F5F5" style="mix-blend-mode: multiply;" x="87" y="42.5" width="36" height="6"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-93" fill="#F5F5F5" style="mix-blend-mode: multiply;" x="87" y="52.5" width="36" height="6"&gt;&lt;/rect&gt;&lt;rect id="矩形复制-94" fill="#F5F5F5" style="mix-blend-mode: multiply;" x="87" y="63.5" width="36" height="6"&gt;&lt;/rect&gt;&lt;/g&gt;&lt;/g&gt;&lt;/g&gt;&lt;/svg&gt;</value>
</data>
</root>

View File

@@ -37,8 +37,9 @@ namespace AntdUI
{
public Alert()
{
hover_close = new ITaskOpacity(nameof(AntdUI.Alert), this);
hover_close = new ITaskOpacity(nameof(Alert), this);
}
#region
int radius = 6;
@@ -159,6 +160,83 @@ namespace AntdUI
}
}
#region
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));
}
}
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? iconratio;
/// <summary>
/// 图标比例
/// </summary>
[Description("图标比例"), Category("外观"), DefaultValue(null)]
public float? IconRatio
{
get => iconratio;
set
{
if (iconratio == value) return;
iconratio = value;
Invalidate();
OnPropertyChanged(nameof(IconRatio));
}
}
float? icongap;
/// <summary>
/// 图标与文字间距比例
/// </summary>
[Description("图标与文字间距比例"), Category("外观"), DefaultValue(null)]
public float? IconGap
{
get => icongap;
set
{
if (icongap == value) return;
icongap = value;
Invalidate();
OnPropertyChanged(nameof(IconGap));
}
}
/// <summary>
/// 是否包含自定义图标
/// </summary>
public bool HasIcon => iconSvg != null;
#endregion
bool loop = false, loopState = false;
/// <summary>
/// 文本轮播
@@ -234,90 +312,6 @@ 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
@@ -377,6 +371,7 @@ namespace AntdUI
public override Rectangle DisplayRectangle => ClientRectangle.PaddingRect(Padding, borWidth / 2F * Config.Dpi);
#endregion
#region
/// <summary>
@@ -386,7 +381,9 @@ namespace AntdUI
public event RBoolEventHandler? CloseChanged;
#endregion
#region
ITaskOpacity hover_close;
RectangleF rect_close;
protected override void OnMouseClick(MouseEventArgs e)
@@ -405,14 +402,16 @@ namespace AntdUI
{
if (closeIcon)
{
hover_close.MaxValue = Colour.Text.Get(nameof(AntdUI.Tag), ColorScheme).A - Colour.TextQuaternary.Get(nameof(AntdUI.Tag), ColorScheme).A;
hover_close.MaxValue = Colour.Text.Get(nameof(Alert), ColorScheme).A - Colour.TextQuaternary.Get(nameof(Alert), 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)
@@ -420,8 +419,7 @@ namespace AntdUI
var rect = DisplayRectangle;
var g = e.Canvas;
bool hasText = string.IsNullOrEmpty(Text);
bool hasIcon = HasIcon;
if (icon == TType.None && !hasIcon)
if (icon == TType.None && !HasIcon)
{
if (loop)
{
@@ -501,17 +499,11 @@ namespace AntdUI
if (font_size == null && !hasText) font_size = g.MeasureText(Text, Font);
if (font_size.HasValue)
{
int icon_size = (int)(sizeT.Height * iconratio), gap = (int)(icon_size * icongap);
int icon_size = (int)(sizeT.Height * (iconratio ?? .86F)), gap = (int)(icon_size * (icongap ?? .4F));
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();
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);
g.PaintIcons(icon, iconSvg, rect_icon, Colour.BgBase, nameof(Alert), ColorScheme);
}
}
else
@@ -523,45 +515,31 @@ namespace AntdUI
}
if (string.IsNullOrEmpty(TextTitle))
{
int icon_size = (int)(sizeT.Height * iconratio), gap = (int)(icon_size * icongap);
int icon_size = (int)(sizeT.Height * (iconratio ?? .86F)), gap = (int)(icon_size * (icongap ?? .4F));
var rect_icon = new Rectangle(rect.X + gap, rect.Y + (rect.Height - icon_size) / 2, icon_size, icon_size);
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);
g.PaintIcons(icon, iconSvg, 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);
PaintCloseIcon(g, rect_txt, .4F);
}
else
{
using (var font_title = new Font(Font.FontFamily, Font.Size * 1.14F, Font.Style))
{
int icon_size = (int)(sizeT.Height * (iconratio + 0.2F)), gap = (int)(icon_size * (icongap + 0.1F));
int icon_size = (int)(sizeT.Height * (iconratio ?? 1.2F)), gap = (int)(icon_size * (icongap ?? .5F));
var rect_icon = new Rectangle(rect.X + gap, rect.Y + gap, icon_size, icon_size);
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);
g.PaintIcons(icon, iconSvg, 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 * .1F);
var desc_y = rect_txt.Bottom + (int)(icon_size * .2F);
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);
PaintCloseIcon(g, rect_txt, .7F);
}
}
}
@@ -572,16 +550,6 @@ 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);
@@ -659,10 +627,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);
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 (LoopInfinite && rect.Width > size.Width)
{
var maxw = rect.Width + rect_txt.Width / 2;
@@ -707,6 +675,19 @@ namespace AntdUI
}
}
void PaintCloseIcon(Canvas g, Rectangle rect, float ratio)
{
if (closeIcon)
{
int size = (int)(rect.Height * ratio);
var rect_arrow = new Rectangle(rect.Right - size, rect.Y + (rect.Height - size) / 2, size, size);
rect_close = rect_arrow;
if (hover_close.Animation) g.PaintIconClose(rect_arrow, Helper.ToColor(hover_close.Value + Colour.TextQuaternary.Get(nameof(Alert), ColorScheme).A, Colour.Text.Get(nameof(Alert), ColorScheme)));
else if (hover_close.Switch) g.PaintIconClose(rect_arrow, Colour.Text.Get(nameof(Alert), ColorScheme));
else g.PaintIconClose(rect_arrow, Colour.TextQuaternary.Get(nameof(Alert), ColorScheme));
}
}
#endregion
public override Rectangle ReadRectangle => DisplayRectangle;

View File

@@ -898,6 +898,7 @@ namespace AntdUI
if (item.buttons == null) continue;
foreach (var btn in item.buttons)
{
if (!btn.Visible || !btn.Enabled) continue;
if (btn.Contains(e.X, e.Y))
{
item.MDown = true;
@@ -923,6 +924,7 @@ namespace AntdUI
if (item.buttons == null) continue;
foreach (var btn in item.buttons)
{
if (!btn.Visible || !btn.Enabled) continue;
if (btn.Contains(e.X, e.Y))
{
if (btn.SwitchMode)
@@ -969,6 +971,7 @@ namespace AntdUI
if (item.buttons == null) continue;
foreach (var btn in item.buttons)
{
if (!btn.Visible || !btn.Enabled) continue;
if (btn.Contains(e.X, e.Y))
{
btn.hasFocus = btn.AnimationHover = true;
@@ -1006,6 +1009,7 @@ namespace AntdUI
if (item.buttons == null || item.buttons.Count == 0) continue;
foreach (var btn in item.buttons)
{
if (!btn.Visible || !btn.Enabled) continue;
if (btn.rect.Contains(x, y))
{
OpenTip(btn);
@@ -1063,6 +1067,7 @@ namespace AntdUI
if (item.buttons == null || item.buttons.Count == 0) return;
foreach (var btn in item.buttons)
{
if (!btn.Visible || !btn.Enabled) continue;
btn.Select = false;
}
}

View File

@@ -34,22 +34,10 @@ namespace AntdUI
[Description("HyperlinkLabel 超链接文本")]
[ToolboxItem(true)]
[DefaultProperty("Text")]
[DefaultEvent("LinkClicked")]
[Designer(typeof(IControlDesigner))]
public class HyperlinkLabel : IControl
{
#region
private LinkAppearance _normalStyle = new();
private LinkAppearance _hoverStyle = new()
{
LinkColor = Color.Red,
UnderlineColor = Color.Red
};
private string _plainText = string.Empty;
public event LinkClickedEventHandler? LinkClicked;
#endregion
#region
Color? fore;
@@ -97,6 +85,27 @@ namespace AntdUI
#endregion
#region
ContentAlignment textAlign = ContentAlignment.MiddleLeft;
/// <summary>
/// 文本位置
/// </summary>
[Description("文本位置"), Category("Appearance"), DefaultValue(ContentAlignment.MiddleLeft)]
public ContentAlignment TextAlign
{
get => textAlign;
set
{
if (textAlign == value) return;
textAlign = value;
Invalidate();
OnPropertyChanged(nameof(TextAlign));
}
}
#endregion
#region
int shadow = 0;
@@ -178,38 +187,58 @@ namespace AntdUI
#endregion
LinkAppearance? normalStyle;
/// <summary>
/// 常规状态下链接的样式
/// </summary>
[Category("Appearance")]
[Description("常规状态下链接的样式")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public LinkAppearance NormalStyle
[Description("常规状态下链接的样式"), Category("Appearance"), DefaultValue(null)]
public LinkAppearance? NormalStyle
{
get { return _normalStyle; }
get
{
normalStyle ??= new LinkAppearance();
return normalStyle;
}
set
{
_normalStyle = value;
if (normalStyle == value) return;
normalStyle = value;
Invalidate();
OnPropertyChanged(nameof(NormalStyle));
}
}
private bool ShouldSerializeNormalStyle() => normalStyle != null && !normalStyle.IsDefault();
private void ResetNormalStyle() => normalStyle = null;
LinkAppearance? hoverStyle;
/// <summary>
/// 鼠标悬停时链接的样式
/// </summary>
[Category("Appearance")]
[Description("鼠标悬停时链接的样式")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public LinkAppearance HoverStyle
[Description("鼠标悬停时链接的样式"), Category("Appearance"), DefaultValue(null)]
public LinkAppearance? HoverStyle
{
get { return _hoverStyle; }
get
{
hoverStyle ??= new LinkAppearance();
return hoverStyle;
}
set
{
_hoverStyle = value;
if (hoverStyle == value) return;
hoverStyle = value;
Invalidate();
OnPropertyChanged(nameof(HoverStyle));
}
}
private bool ShouldSerializeHoverStyle() => hoverStyle != null && !hoverStyle.IsDefault();
private void ResetHoverStyle() => hoverStyle = null;
Padding _linkPadding = new(2, 0, 2, 0);
/// <summary>
/// 链接与周围字符之间的距离
@@ -260,60 +289,129 @@ namespace AntdUI
void PaintText(Canvas g, string? text, Color color, Rectangle rect)
{
int usex = rect.X, usey = rect.Y;
// 计算文本的总尺寸以支持对齐
var totalSize = CalculateTextSize(g, text);
// 根据 TextAlign 计算起始位置
int startX = rect.X, startY = rect.Y;
switch (textAlign)
{
case ContentAlignment.TopLeft:
startX = rect.X;
startY = rect.Y;
break;
case ContentAlignment.TopCenter:
startX = rect.X + (rect.Width - totalSize.Width) / 2;
startY = rect.Y;
break;
case ContentAlignment.TopRight:
startX = rect.Right - totalSize.Width;
startY = rect.Y;
break;
case ContentAlignment.MiddleLeft:
startX = rect.X;
startY = rect.Y + (rect.Height - totalSize.Height) / 2;
break;
case ContentAlignment.MiddleCenter:
startX = rect.X + (rect.Width - totalSize.Width) / 2;
startY = rect.Y + (rect.Height - totalSize.Height) / 2;
break;
case ContentAlignment.MiddleRight:
startX = rect.Right - totalSize.Width;
startY = rect.Y + (rect.Height - totalSize.Height) / 2;
break;
case ContentAlignment.BottomLeft:
startX = rect.X;
startY = rect.Bottom - totalSize.Height;
break;
case ContentAlignment.BottomCenter:
startX = rect.X + (rect.Width - totalSize.Width) / 2;
startY = rect.Bottom - totalSize.Height;
break;
case ContentAlignment.BottomRight:
startX = rect.Right - totalSize.Width;
startY = rect.Bottom - totalSize.Height;
break;
}
int usex = startX, usey = startY;
foreach (var part in _linkParts)
{
if (part.Href == null)
{
var size = g.MeasureText(part.Text, Font);
if (usex + size.Width > rect.Width)
if (usex + size.Width > rect.Right && usex > startX)
{
usex = rect.X;
usex = startX;
usey += size.Height;
}
part.Bounds = new Rectangle(usex, usey, size.Width, size.Height);
g.DrawText(part.Text, Font, color, part.Bounds);
usex += size.Width;
}
else if (part.Hover)
else if (part.Hover) PaintText(g, rect, part, startX, ref usex, ref usey, Colour.PrimaryActive, hoverStyle);
else PaintText(g, rect, part, startX, ref usex, ref usey, Colour.Primary, normalStyle);
}
}
void PaintText(Canvas g, Rectangle rect, LinkPart part, int startX, ref int usex, ref int usey, Colour colour, LinkAppearance? style)
{
if (style == null)
{
var size = g.MeasureText(part.Text, Font).DeflateSize(LinkPadding);
if (usex + size.Width > rect.Right && usex > startX)
{
using (var font = new Font(Font, HoverStyle.LinkStyle & ~FontStyle.Underline))
{
var size = g.MeasureText(part.Text, Font).DeflateSize(LinkPadding);
if (usex + size.Width > rect.Width)
{
usex = rect.X;
usey += size.Height;
}
part.Bounds = new Rectangle(usex, usey, size.Width, size.Height);
g.DrawText(part.Text, font, HoverStyle.LinkColor ?? Style.Get(Colour.PrimaryActive, nameof(HyperlinkLabel)), part.Bounds);
PaintText(g, HoverStyle, Style.Get(Colour.PrimaryActive, nameof(HyperlinkLabel)), part.Bounds);
usex += size.Width;
}
usex = startX;
usey += size.Height;
}
else
part.Bounds = new Rectangle(usex, usey, size.Width, size.Height);
g.DrawText(part.Text, Font, Style.Get(colour, nameof(HyperlinkLabel)), part.Bounds);
usex += size.Width;
}
else
{
using (var font = new Font(Font, style.LinkStyle & ~FontStyle.Underline))
{
using (var font = new Font(Font, NormalStyle.LinkStyle & ~FontStyle.Underline))
var size = g.MeasureText(part.Text, Font).DeflateSize(LinkPadding);
if (usex + size.Width > rect.Right && usex > startX)
{
var size = g.MeasureText(part.Text, Font).DeflateSize(LinkPadding);
if (usex + size.Width > rect.Width)
{
usex = rect.X;
usey += size.Height;
}
part.Bounds = new Rectangle(usex, usey, size.Width, size.Height);
g.DrawText(part.Text, font, NormalStyle.LinkColor ?? Style.Get(Colour.Primary, nameof(HyperlinkLabel)), part.Bounds);
PaintText(g, NormalStyle, Style.Get(Colour.Primary, nameof(HyperlinkLabel)), part.Bounds);
usex += size.Width;
usex = startX;
usey += size.Height;
}
part.Bounds = new Rectangle(usex, usey, size.Width, size.Height);
g.DrawText(part.Text, font, style.LinkColor ?? Style.Get(colour, nameof(HyperlinkLabel)), part.Bounds);
PaintText(g, style, Style.Get(colour, nameof(HyperlinkLabel)), part.Bounds);
usex += size.Width;
}
}
}
private Size CalculateTextSize(Canvas g, string? text)
{
if (string.IsNullOrEmpty(text) || _linkParts.Length == 0) return Size.Empty;
int totalWidth = 0, maxHeight = 0;
foreach (var part in _linkParts)
{
Size partSize;
if (part.Href == null || normalStyle == null) partSize = g.MeasureText(part.Text, Font);
else
{
using (var font = new Font(Font, normalStyle.LinkStyle & ~FontStyle.Underline))
{
partSize = g.MeasureText(part.Text, font).DeflateSize(LinkPadding);
}
}
totalWidth += partSize.Width;
maxHeight = Math.Max(maxHeight, partSize.Height);
}
return new Size(totalWidth, maxHeight);
}
void PaintText(Canvas g, LinkAppearance style, Color color, Rectangle rect)
{
if (style.UnderlineThickness > 0)
@@ -328,6 +426,12 @@ namespace AntdUI
#endregion
#region
public event LinkClickedEventHandler? LinkClicked;
#endregion
#region
/// <summary>
@@ -435,6 +539,7 @@ namespace AntdUI
#region
LinkPart[] _linkParts = new LinkPart[0];
string _plainText = string.Empty;
private void ParseText()
{
if (text == null)
@@ -612,6 +717,14 @@ namespace AntdUI
[Description("下划线厚度0为不显示下划线"), DefaultValue(1)]
public int UnderlineThickness { get; set; } = 1;
internal bool IsDefault()
{
return LinkColor == null
&& LinkStyle == FontStyle.Regular
&& UnderlineColor == null
&& UnderlineThickness == 1;
}
public override string ToString() => "LinkAppearance";
}

View File

@@ -100,6 +100,12 @@ namespace AntdUI
[Description("下拉文本方向"), Category("外观"), DefaultValue(TAlign.Left)]
public TAlign DropDownTextAlign { get; set; } = TAlign.Left;
/// <summary>
/// 是否允许回车键触发下拉框
/// </summary>
[Description("是否允许回车键触发下拉框"), Category("行为"), DefaultValue(true)]
public bool EnterDropDown { get; set; } = true;
/// <summary>
/// 下拉为空关闭
/// </summary>
@@ -568,7 +574,7 @@ namespace AntdUI
ExpandDrop = true;
return true;
case Keys.Enter:
ExpandDrop = true;
if (EnterDropDown) ExpandDrop = true;
break;
}
return r;
@@ -699,10 +705,12 @@ namespace AntdUI
public Image? Icon { get; set; }
public string? IconSvg { get; set; }
/// <summary>
/// 图标比例 (默认0.75f)
/// 图标比例
/// </summary>
public float? IconRatio { get; set; }
public float? IconRatio { get; set; }
string _text;
/// <summary>
/// 文本
@@ -849,6 +857,12 @@ namespace AntdUI
return this;
}
public SelectItem SetIconRatio(float? value)
{
IconRatio = value;
return this;
}
#endregion
public SelectItem SetSub(params object[] value)

View File

@@ -87,6 +87,20 @@ namespace AntdUI
[Description("文本"), Category("国际化"), DefaultValue(null)]
public string? LocalizationText { get; set; }
[Description("加载指示符"), Category("外观"), DefaultValue(null)]
public Image? Indicator
{
get => config.Indicator;
set => config.Indicator = value;
}
[Description("加载指示符SVG"), Category("外观"), DefaultValue(null)]
public string? IndicatorSvg
{
get => config.IndicatorSvg;
set => config.IndicatorSvg = value;
}
#endregion
#region
@@ -156,10 +170,80 @@ namespace AntdUI
/// </summary>
public int? Radius { get; set; }
/// <summary>
/// 加载指示符
/// </summary>
public Image? Indicator { get; set; }
/// <summary>
/// 加载指示符SVG
/// </summary>
public string? IndicatorSvg { get; set; }
/// <summary>
/// 进度
/// </summary>
public float? Value { get; set; }
/// <summary>
/// 进度速率
/// </summary>
public float? Rate { get; set; }
#region
public Config SetText(string? value)
{
Text = value;
return this;
}
public Config SetBack(Color? value)
{
Back = value;
return this;
}
public Config SetFore(Color? value)
{
Fore = value;
return this;
}
public Config SetColor(Color? value)
{
Color = value;
return this;
}
public Config SetFont(Font? value)
{
Font = value;
return this;
}
public Config SetRadius(int? value)
{
Radius = value;
return this;
}
public Config SetValue(float? value)
{
Value = value;
return this;
}
public Config SetIndicator(Image? value)
{
Indicator = value;
return this;
}
public Config SetIndicator(string? value)
{
IndicatorSvg = value;
return this;
}
public Config SetRate(float? value)
{
Rate = value;
return this;
}
#endregion
}
#region
@@ -251,38 +335,32 @@ namespace AntdUI
public void Start(IControl control)
{
Stop();
bool ProgState = false;
thread = new ITask(control, () =>
{
if (lnull) LineAngle = LineAngle.Calculate(2F);
else
{
if (ProgState)
{
LineAngle = LineAngle.Calculate(9F);
LineWidth = LineWidth.Calculate(0.6F);
if (LineWidth > 75) ProgState = false;
}
else
{
LineAngle = LineAngle.Calculate(9.6F);
LineWidth = LineWidth.Calculate(-0.6F);
if (LineWidth < 6) ProgState = true;
}
}
if (LineAngle >= 360) LineAngle = 0;
Animation(ref ProgState);
control.Invalidate();
return true;
}, 10);
}
public void Start(ILayeredForm control)
{
Stop();
bool ProgState = false;
thread = new ITask(control, () =>
{
if (lnull) LineAngle = LineAngle.Calculate(2F);
else
{
Animation(ref ProgState);
control.Print();
return true;
}, 10);
}
void Animation(ref bool ProgState)
{
switch (mode)
{
case 0:
if (ProgState)
{
LineAngle = LineAngle.Calculate(9F);
@@ -295,16 +373,28 @@ namespace AntdUI
LineWidth = LineWidth.Calculate(-0.6F);
if (LineWidth < 6) ProgState = true;
}
}
if (LineAngle >= 360) LineAngle = 0;
control.Print();
return true;
}, 10);
break;
case 1:
LineAngle = LineAngle.Calculate(2F);
break;
case 2:
default:
LineAngle = LineAngle.Calculate(rate ?? 12F);
break;
}
if (LineAngle >= 360) LineAngle = 0;
}
public void Stop()
{
thread?.Dispose();
thread = null;
}
readonly StringFormat s_f = Helper.SF_ALL();
bool lnull = false;
float? rate;
int mode = 0;
public void Paint(Canvas g, Rectangle rect, Spin.Config config, Control control)
{
var font = config.Font ?? control.Font;
@@ -317,24 +407,40 @@ namespace AntdUI
rect_prog.Offset(0, -size2);
g.DrawText(config.Text, font, config.Fore ?? Colour.Primary.Get(nameof(Spin)), new Rectangle(rect.X, y, rect.Width, prog_size), s_f);
}
g.DrawEllipse(Colour.Fill.Get(nameof(Spin)), size, rect_prog);
using (var brush = new Pen(config.Color ?? Colour.Primary.Get(nameof(Spin)), size))
var color = config.Color ?? Colour.Primary.Get(nameof(Spin));
if (config.Indicator != null || config.IndicatorSvg != null)
{
brush.StartCap = brush.EndCap = LineCap.Round;
if (config.Value.HasValue)
rate = config.Rate;
mode = 2;
var size22 = rprog_size / 2F;
g.TranslateTransform(rect_prog.X + size22, rect_prog.Y + size22);
g.RotateTransform(LineAngle);
var rect_center = new Rectangle(-size2, -size2, rprog_size, rprog_size);
if (config.Indicator != null) g.Image(config.Indicator, rect_center);
if (config.IndicatorSvg != null) g.GetImgExtend(config.IndicatorSvg, rect_center, color);
g.ResetTransform();
}
else
{
g.DrawEllipse(Colour.Fill.Get(nameof(Spin)), size, rect_prog);
using (var brush = new Pen(color, size))
{
lnull = true;
g.DrawArc(brush, rect_prog, LineAngle, config.Value.Value * 360F);
}
else
{
lnull = false;
g.DrawArc(brush, rect_prog, LineAngle, LineWidth * 3.6F);
brush.StartCap = brush.EndCap = LineCap.Round;
if (config.Value.HasValue)
{
mode = 1;
g.DrawArc(brush, rect_prog, LineAngle, config.Value.Value * 360F);
}
else
{
mode = 0;
g.DrawArc(brush, rect_prog, LineAngle, LineWidth * 3.6F);
}
}
}
}
public void Dispose() => thread?.Dispose();
public void Dispose() => Stop();
}
internal class SpinForm : ILayeredFormOpacity
@@ -366,7 +472,6 @@ namespace AntdUI
}
}
public override string name => nameof(Spin);
Func<GraphicsPath>? RenderRegion;
@@ -376,21 +481,48 @@ namespace AntdUI
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
spin_core.Start(this);
control.VisibleChanged += Parent_VisibleChanged;
control.LocationChanged += Parent_LocationChanged;
control.SizeChanged += Parent_SizeChanged;
if (control is TabPage page) page.ShowedChanged += Parent_VisibleChanged;
if (parent != null)
{
parent.VisibleChanged += Parent_VisibleChanged;
parent.LocationChanged += Parent_LocationChanged;
parent.SizeChanged += Parent_SizeChanged;
}
LoadVisible();
}
bool visible = false;
void LoadVisible()
{
var tmp = GetVisible();
if (visible == tmp) return;
visible = tmp;
if (tmp) spin_core.Start(this);
else
{
spin_core.Stop();
Print();
}
}
bool GetVisible()
{
if (control is TabPage page) return page.Showed && page.Visible;
return control.Visible;
}
private void Parent_VisibleChanged(object? sender, EventArgs e) => LoadVisible();
private void Parent_LocationChanged(object? sender, EventArgs e)
{
LoadVisible();
if (control is Form form) SetLocation(form.Location);
else SetLocation(control.PointToScreen(Point.Empty));
}
private void Parent_SizeChanged(object? sender, EventArgs e)
{
LoadVisible();
if (control is Form form)
{
SetSize(form.Size);
@@ -410,30 +542,33 @@ namespace AntdUI
{
Rectangle rect_read = TargetRectXY, rect = HasBor ? new Rectangle(Bor, 0, rect_read.Width - Bor * 2, rect_read.Height - Bor) : rect_read;
var original_bmp = new Bitmap(rect_read.Width, rect_read.Height);
using (var g = Graphics.FromImage(original_bmp).HighLay(true))
if (visible)
{
using (var brush = new SolidBrush(config.Back ?? Style.rgba(Colour.BgBase.Get(nameof(Spin)), .8F)))
using (var g = Graphics.FromImage(original_bmp).HighLay(true))
{
if (RenderRegion == null)
using (var brush = new SolidBrush(config.Back ?? Style.rgba(Colour.BgBase.Get(nameof(Spin)), .8F)))
{
if (Radius > 0)
if (RenderRegion == null)
{
using (var path = rect.RoundPath(Radius))
if (Radius > 0)
{
using (var path = rect.RoundPath(Radius))
{
g.Fill(brush, path);
}
}
else g.Fill(brush, rect);
}
else
{
using (var path = RenderRegion())
{
g.Fill(brush, path);
}
}
else g.Fill(brush, rect);
}
else
{
using (var path = RenderRegion())
{
g.Fill(brush, path);
}
}
spin_core.Paint(g, rect, config, this);
}
spin_core.Paint(g, rect, config, this);
}
return original_bmp;
}
@@ -443,8 +578,13 @@ namespace AntdUI
protected override void Dispose(bool disposing)
{
spin_core.Dispose();
control.VisibleChanged -= Parent_VisibleChanged;
control.LocationChanged -= Parent_LocationChanged;
control.SizeChanged -= Parent_SizeChanged;
if (control is TabPage page) page.ShowedChanged -= Parent_VisibleChanged;
if (parent != null)
{
parent.VisibleChanged -= Parent_VisibleChanged;
parent.LocationChanged -= Parent_LocationChanged;
parent.SizeChanged -= Parent_SizeChanged;
}

View File

@@ -71,9 +71,11 @@ namespace AntdUI
{
if (_editControls.TryRemove(id, out var obj))
{
id.LostFocus -= InputEdit_LostFocus;
if (id is Select select)
{
select.SelectedValueChanged -= InputEdit_SelectedValueChanged;
select.ClosedItem -= InputEdit_SelectedValueChanged;
if (obj[1] is Action<bool, object?> call)
{
obj[1] = null;
@@ -143,7 +145,7 @@ namespace AntdUI
else if (cellText.COLUMN.Align == ColumnAlign.Right) tmp_input.TextAlign = HorizontalAlignment.Right;
var arge = new TableBeginEditInputStyleEventArgs(value, it.RECORD, i_row, i_col, column, tmp_input);
CellBeginEditInputStyle?.Invoke(this, arge);
var action = new Action<bool, string>((cf, _value) =>
ShowInput(arge.Input, (cf, _value) =>
{
var e = new TableEndEditEventArgs(_value, it.RECORD, i_row, i_col, column);
arge.Call?.Invoke(e);
@@ -160,7 +162,6 @@ namespace AntdUI
CellEditComplete?.Invoke(this, new ITableEventArgs(it.RECORD, i_row, i_col, column));
}
});
ShowInput(arge.Input, action);
});
}
else if (cell is TCellSelect cellSelect)
@@ -280,6 +281,14 @@ namespace AntdUI
return true;
}
}
else if (value is DateTime)
{
if (DateTime.TryParse(_value, out var v))
{
read = v;
return true;
}
}
else
{
read = _value;
@@ -395,50 +404,21 @@ 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;
if (AddEditInput(select, old, call))
{
select.SelectedValueChanged += InputEdit_SelectedValueChanged;
select.ClosedItem += Select_ClosedItem;
select.LostFocus += Select_LostFocus;
select.ClosedItem += InputEdit_SelectedValueChanged;
select.Focus();
}
}
private void Select_LostFocus(object? sender, EventArgs e)
{
if (sender is Select select)
{
Select_ClosedItem(sender, new ObjectNEventArgs(select.SelectedValue));
}
}
private void Select_ClosedItem(object sender, ObjectNEventArgs e)
{
if (sender is Select select)
{
select.SelectedValueChanged -= InputEdit_SelectedValueChanged;
select.ClosedItem -= Select_ClosedItem;
select.LostFocus -= Select_LostFocus;
EditModeClose();
}
}
void InputEdit_KeyPress(object? sender, KeyPressEventArgs e)
{
if (sender is Input input)
@@ -446,38 +426,12 @@ namespace AntdUI
if (e.KeyChar == 13)
{
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)
{
obj[1] = null;
call(((string)obj[0]!) == input.Text, input.Text);
}
}
EditModeClose();
}
}
}
void InputEdit_SelectedValueChanged(object? sender, ObjectNEventArgs e)
{
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)
{
obj[1] = null;
call(obj[0] == select.SelectedValue, select.SelectedValue);
}
}
EditModeClose();
}
}
void InputEdit_SelectedValueChanged(object? sender, ObjectNEventArgs e) => EditModeClose();
void InputEdit_LostFocus(object? sender, EventArgs e) => EditModeClose();
#endregion
@@ -493,6 +447,7 @@ namespace AntdUI
if (_editControls.TryAdd(input, new object?[] { txt, action }))
{
Controls.Add(input);
input.LostFocus += InputEdit_LostFocus;
return true;
}
else input.Dispose();

View File

@@ -313,12 +313,20 @@ namespace AntdUI
if (rows == null) return;
if (OnTouchUp())
{
if (cellMDown == null) return;
if (cellMDown == null)
{
EditModeClose();
return;
}
MouseUpRow(rows, cellMDown, btnMDown, e);
}
else
{
if (btnMDown == null) return;
if (btnMDown == null)
{
EditModeClose();
return;
}
if (btnMDown.cell.ExtraMouseDown)
{
CellButtonUp?.Invoke(this, new TableButtonEventArgs(btnMDown.cell, btnMDown.row.RECORD, btnMDown.i_row, btnMDown.i_cel, btnMDown.cell.PARENT.COLUMN, RealRect(btnMDown), e));

View File

@@ -1082,7 +1082,7 @@ namespace AntdUI
break;
}
}
}
public SelectItem? value { get; set; }
@@ -1103,7 +1103,7 @@ namespace AntdUI
if (!emptyIcon)
{
int gapIcon = gap.x / 2;
int wh = (int)((_rect.Height - gap.x) * value.IconRatio??0.75f);
int wh = (int)((_rect.Height - gap.x) * value.IconRatio ?? 0.7f);
rect_icon = new Rectangle(_rect.X + (emptyText ? (_rect.Width - wh) / 2 : gap.x), _rect.Y + (_rect.Height - wh) / 2, wh, wh);
if (COLUMN.CellType != SelectCellType.Text) rect_text = new Rectangle(rect_icon.X + gapIcon + wh, rect_icon.Y, RECT_REAL.Width - rect_icon.Width + gapIcon, rect_icon.Height);
}

View File

@@ -457,9 +457,7 @@ namespace AntdUI
{
if (items == null) return;
if (items.Count <= _select || _select < 0) return;
var it = items[_select];
if (IsHandleCreated) BeginInvoke(it.BringToFront);
else it.BringToFront();
for (int i = 0; i < items.Count; i++) items[i].Showed = i == _select;
}
}
@@ -1625,13 +1623,13 @@ namespace AntdUI
it.Invoke(() =>
{
it.Controls.Add(item);
if (top) item.BringToFront();
if (top) item.Showed = true;
});
}
else
{
it.Controls.Add(item);
if (top) item.BringToFront();
if (top) item.Showed = true;
}
};
action_del = (item, index) =>
@@ -1846,6 +1844,40 @@ namespace AntdUI
#endregion
#region
bool showed = false;
[Description("显示的"), Category("外观"), DefaultValue(false)]
public bool Showed
{
get => showed;
set
{
if (showed == value) return;
showed = value;
ShowedChanged?.Invoke(this, EventArgs.Empty);
if (value)
{
if (IsHandleCreated) BeginInvoke(BringToFront);
else BringToFront();
}
}
}
public event EventHandler? ShowedChanged;
#endregion
#if NET40 || NET46 || NET48
[EditorBrowsable(EditorBrowsableState.Advanced)]
public IAsyncResult BeginInvoke(Action method) => BeginInvoke(method, null);
public void Invoke(Action method) => _ = Invoke(method, null);
public T Invoke<T>(Func<T> method) => (T)Invoke(method, null);
#endif
public override string ToString() => Text;
}
}

View File

@@ -127,7 +127,6 @@ 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,12 +202,7 @@ namespace AntdUI
}
}
}
try
{
if (temp == null) return null;
return new Bitmap(temp);
}
catch { return null; }
return new Bitmap(temp);
}
protected override void OnMouseClick(MouseEventArgs e)

View File

@@ -556,7 +556,7 @@ namespace AntdUI
{
nodata = false;
int sp = (int)Config.Dpi, padd = (int)(text_height * .18F), padd2 = padd * 2, gap_x = (int)(DPadding.Width * Config.Dpi), gap_y = (int)(DPadding.Height * Config.Dpi),
icon_size = (int)(text_height * (items[0] is SelectItem ? ((SelectItem)items[0]).IconRatio ?? 0.75f : .7F)), icon_gap = (int)(text_height * .25F), item_height = text_height + gap_y * 2, icon_xy = (item_height - icon_size) / 2,
icon_size = (int)(text_height * .7F), icon_gap = (int)(text_height * .25F), item_height = text_height + gap_y * 2, icon_xy = (item_height - icon_size) / 2,
gap_x2 = gap_x * 2, gap_y2 = gap_y * 2;
tmp_padd = padd;
@@ -649,6 +649,7 @@ namespace AntdUI
{
if (obj is SelectItem it)
{
if (it.IconRatio.HasValue) icon_size = (int)(text_height * it.IconRatio.Value);
int tmp = g.MeasureText(it.Text + it.SubText, Font).Width;
if (it.Online > -1) tmp += icon_size;
if (it.Icon != null || it.IconSvg != null) tmp += icon_size + icon_gap;
@@ -682,6 +683,11 @@ namespace AntdUI
var rect = new Rectangle(padd, padd + y, maxwr, item_height);
if (value is SelectItem it)
{
if (it.IconRatio.HasValue)
{
icon_size = (int)(text_height * it.IconRatio.Value);
icon_xy = (item_height - icon_size) / 2;
}
int ux = gap_x, uw = gap_x2;
item = new ObjectItem(it, i, rect) { NoIndex = no_id };
if (it.Online > -1)

View File

@@ -464,6 +464,7 @@ namespace AntdUI
{
if (obj is SelectItem it)
{
if (it.IconRatio.HasValue) icon_size = (int)(text_height * it.IconRatio.Value);
int tmp = g.MeasureText(it.Text + it.SubText, Font).Width;
if (it.Online > -1) tmp += icon_size;
if (it.Icon != null || it.IconSvg != null) tmp += icon_size + icon_gap;
@@ -495,6 +496,11 @@ namespace AntdUI
var rect = new Rectangle(padd, padd + y, maxwr, item_height);
if (value is SelectItem it)
{
if (it.IconRatio.HasValue)
{
icon_size = (int)(text_height * it.IconRatio.Value);
icon_xy = (item_height - icon_size) / 2;
}
int ux = gap_x, uw = gap_x2;
item = new ObjectItem(it, i, rect) { NoIndex = no_id };
if (it.Online > -1)

View File

@@ -710,42 +710,86 @@ namespace AntdUI
break;
}
}
internal static void PaintIcons(this Canvas g, TType icon, Rectangle rect, Colour colour, string keyid, TAMode colorScheme)
internal static void PaintIcons(this Canvas g, TType icon, string? svg, Rectangle rect, Colour colour, string keyid, TAMode colorScheme)
{
using (var brush = new SolidBrush(Colour.BgBase.Get(keyid, colorScheme)))
if (svg == null)
{
g.FillEllipse(brush, new Rectangle(rect.X + 1, rect.Y + 1, rect.Width - 2, rect.Height - 2));
using (var brush = new SolidBrush(Colour.BgBase.Get(keyid, colorScheme)))
{
g.FillEllipse(brush, new Rectangle(rect.X + 1, rect.Y + 1, rect.Width - 2, rect.Height - 2));
}
switch (icon)
{
case TType.Success:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoSuccess, rect, Colour.Success.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Info:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoInfo, rect, Colour.Info.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Warn:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoWarn, rect, Colour.Warning.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Error:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoError, rect, Colour.Error.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
}
}
switch (icon)
else
{
case TType.Success:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoSuccess, rect, Colour.Success.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Info:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoInfo, rect, Colour.Info.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Warn:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoWarn, rect, Colour.Warning.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Error:
using (var bmp = SvgExtend.GetImgExtend(SvgDb.IcoError, rect, Colour.Error.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
switch (icon)
{
case TType.Success:
using (var bmp = SvgExtend.GetImgExtend(svg, rect, Colour.Success.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Info:
using (var bmp = SvgExtend.GetImgExtend(svg, rect, Colour.Info.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Warn:
using (var bmp = SvgExtend.GetImgExtend(svg, rect, Colour.Warning.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
case TType.Error:
using (var bmp = SvgExtend.GetImgExtend(svg, rect, Colour.Error.Get(keyid, colorScheme)))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
default:
using (var bmp = SvgExtend.GetImgExtend(svg, rect))
{
if (bmp == null) return;
g.Image(bmp, rect);
}
break;
}
}
}
internal static void PaintIconGhosts(this Canvas g, TType icon, Rectangle rect, Color color)