💎 新增图表组件和水印组件

This commit is contained in:
机械师
2025-08-29 08:48:35 +00:00
committed by Tom
parent eb461044cb
commit 75410ac625
17 changed files with 3675 additions and 0 deletions

BIN
example/Demo/Controls/Chart.Designer.cs generated Normal file

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,339 @@
// 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
namespace Demo.Controls
{
partial class Watermark
{
/// <summary>
/// 必需的设计器变量。
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// 清理所有正在使用的资源。
/// </summary>
/// <param name="disposing">如果应释放托管资源,为 true否则为 false。</param>
protected override void Dispose(bool disposing)
{
if(disposing)
{
// 清理水印
ClearWatermark();
}
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();
panel8 = new AntdUI.Panel();
divider1 = new AntdUI.Divider();
label7 = new System.Windows.Forms.Label();
btnClear = new AntdUI.Button();
btnPanel = new AntdUI.Button();
lblGap = new AntdUI.Label();
trackGap = new AntdUI.Slider();
lblRotate = new AntdUI.Label();
trackRotate = new AntdUI.Slider();
lblOpacity = new AntdUI.Label();
trackOpacity = new AntdUI.Slider();
label2 = new AntdUI.Label();
inputContent2 = new AntdUI.Input();
label1 = new AntdUI.Label();
inputContent = new AntdUI.Input();
label6 = new AntdUI.Label();
colorPicker = new AntdUI.ColorPicker();
btnForm = new AntdUI.Button();
panel1.SuspendLayout();
panel8.SuspendLayout();
SuspendLayout();
//
// header1
//
header1.Description = "给页面的某个区域加上水印。";
header1.Dock = System.Windows.Forms.DockStyle.Top;
header1.Font = new System.Drawing.Font("Microsoft YaHei UI", 12F);
header1.LocalizationDescription = "Watermark.Description";
header1.LocalizationText = "Watermark.Text";
header1.Location = new System.Drawing.Point(0, 0);
header1.Name = "header1";
header1.Padding = new System.Windows.Forms.Padding(0, 0, 0, 10);
header1.Size = new System.Drawing.Size(835, 74);
header1.TabIndex = 1;
header1.Text = "Watermark 水印";
header1.UseTitleFont = true;
header1.BackClick += header1_BackClick;
//
// panel1
//
panel1.Controls.Add(panel8);
panel1.Controls.Add(btnClear);
panel1.Controls.Add(btnPanel);
panel1.Controls.Add(lblGap);
panel1.Controls.Add(trackGap);
panel1.Controls.Add(lblRotate);
panel1.Controls.Add(trackRotate);
panel1.Controls.Add(lblOpacity);
panel1.Controls.Add(trackOpacity);
panel1.Controls.Add(label2);
panel1.Controls.Add(inputContent2);
panel1.Controls.Add(label1);
panel1.Controls.Add(inputContent);
panel1.Controls.Add(label6);
panel1.Controls.Add(colorPicker);
panel1.Controls.Add(btnForm);
panel1.Dock = System.Windows.Forms.DockStyle.Fill;
panel1.Location = new System.Drawing.Point(0, 74);
panel1.Name = "panel1";
panel1.Size = new System.Drawing.Size(835, 560);
panel1.TabIndex = 4;
//
// panel8
//
panel8.ArrowAlign = AntdUI.TAlign.TL;
panel8.ArrowSize = 10;
panel8.Controls.Add(divider1);
panel8.Controls.Add(label7);
panel8.Location = new System.Drawing.Point(368, 17);
panel8.Name = "panel8";
panel8.Radius = 10;
panel8.Shadow = 24;
panel8.ShadowOpacity = 0.18F;
panel8.ShadowOpacityAnimation = true;
panel8.Size = new System.Drawing.Size(451, 397);
panel8.TabIndex = 41;
//
// divider1
//
divider1.BackColor = System.Drawing.Color.Transparent;
divider1.Dock = System.Windows.Forms.DockStyle.Top;
divider1.Location = new System.Drawing.Point(24, 72);
divider1.Margin = new System.Windows.Forms.Padding(10);
divider1.Name = "divider1";
divider1.Size = new System.Drawing.Size(403, 1);
divider1.TabIndex = 1;
//
// label7
//
label7.BackColor = System.Drawing.Color.Transparent;
label7.Dock = System.Windows.Forms.DockStyle.Top;
label7.Font = new System.Drawing.Font("Microsoft YaHei UI", 15.75F, System.Drawing.FontStyle.Bold);
label7.Location = new System.Drawing.Point(24, 24);
label7.Name = "label7";
label7.Padding = new System.Windows.Forms.Padding(20, 0, 0, 0);
label7.Size = new System.Drawing.Size(403, 48);
label7.TabIndex = 0;
label7.Text = "面板水印";
label7.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
//
// btnClear
//
btnClear.Font = new System.Drawing.Font("Microsoft YaHei UI", 12F);
btnClear.Location = new System.Drawing.Point(250, 400);
btnClear.Name = "btnClear";
btnClear.Size = new System.Drawing.Size(99, 40);
btnClear.TabIndex = 40;
btnClear.Text = "清除水印";
btnClear.Type = AntdUI.TTypeMini.Error;
btnClear.Click += btnClear_Click;
//
// btnPanel
//
btnPanel.Font = new System.Drawing.Font("Microsoft YaHei UI", 12F);
btnPanel.Location = new System.Drawing.Point(145, 400);
btnPanel.Name = "btnPanel";
btnPanel.Size = new System.Drawing.Size(99, 40);
btnPanel.TabIndex = 39;
btnPanel.Text = "面板水印";
btnPanel.Type = AntdUI.TTypeMini.Primary;
btnPanel.Click += btnPanel_Click;
//
// lblGap
//
lblGap.Location = new System.Drawing.Point(38, 322);
lblGap.Name = "lblGap";
lblGap.Size = new System.Drawing.Size(206, 26);
lblGap.TabIndex = 38;
lblGap.Text = "间距: 50px";
//
// trackGap
//
trackGap.Location = new System.Drawing.Point(38, 354);
trackGap.MaxValue = 500;
trackGap.MinValue = 50;
trackGap.Name = "trackGap";
trackGap.ShowValue = true;
trackGap.Size = new System.Drawing.Size(245, 40);
trackGap.TabIndex = 37;
trackGap.Value = 50;
trackGap.ValueChanged += trackGap_ValueChanged;
//
// lblRotate
//
lblRotate.Location = new System.Drawing.Point(38, 244);
lblRotate.Name = "lblRotate";
lblRotate.Size = new System.Drawing.Size(206, 26);
lblRotate.TabIndex = 36;
lblRotate.Text = "旋转角度:-22°";
//
// trackRotate
//
trackRotate.Location = new System.Drawing.Point(38, 276);
trackRotate.MaxValue = 90;
trackRotate.MinValue = -90;
trackRotate.Name = "trackRotate";
trackRotate.ShowValue = true;
trackRotate.Size = new System.Drawing.Size(245, 40);
trackRotate.TabIndex = 35;
trackRotate.Value = 22;
trackRotate.ValueChanged += trackRotate_ValueChanged;
//
// lblOpacity
//
lblOpacity.Location = new System.Drawing.Point(38, 166);
lblOpacity.Name = "lblOpacity";
lblOpacity.Size = new System.Drawing.Size(206, 26);
lblOpacity.TabIndex = 34;
lblOpacity.Text = "透明度15%";
//
// trackOpacity
//
trackOpacity.Location = new System.Drawing.Point(38, 198);
trackOpacity.MinValue = 1;
trackOpacity.Name = "trackOpacity";
trackOpacity.ShowValue = true;
trackOpacity.Size = new System.Drawing.Size(245, 40);
trackOpacity.TabIndex = 33;
trackOpacity.Value = 15;
trackOpacity.ValueChanged += trackOpacity_ValueChanged;
//
// label2
//
label2.Location = new System.Drawing.Point(20, 116);
label2.Name = "label2";
label2.Size = new System.Drawing.Size(81, 26);
label2.TabIndex = 32;
label2.Text = "水印颜色:";
label2.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// inputContent2
//
inputContent2.Location = new System.Drawing.Point(102, 56);
inputContent2.Name = "inputContent2";
inputContent2.Size = new System.Drawing.Size(260, 44);
inputContent2.TabIndex = 31;
//
// label1
//
label1.Location = new System.Drawing.Point(20, 65);
label1.Name = "label1";
label1.Size = new System.Drawing.Size(81, 26);
label1.TabIndex = 30;
label1.Text = "副内容:";
label1.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// inputContent
//
inputContent.Location = new System.Drawing.Point(102, 6);
inputContent.Name = "inputContent";
inputContent.Size = new System.Drawing.Size(260, 44);
inputContent.TabIndex = 29;
inputContent.Text = "AntdUI Watermark";
//
// label6
//
label6.Location = new System.Drawing.Point(20, 15);
label6.Name = "label6";
label6.Size = new System.Drawing.Size(81, 26);
label6.TabIndex = 28;
label6.Text = "水印内容:";
label6.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
//
// colorPicker
//
colorPicker.AutoSizeMode = AntdUI.TAutoSize.Auto;
colorPicker.Location = new System.Drawing.Point(102, 106);
colorPicker.Name = "colorPicker";
colorPicker.ShowText = true;
colorPicker.Size = new System.Drawing.Size(124, 45);
colorPicker.TabIndex = 27;
colorPicker.Value = System.Drawing.Color.Black;
colorPicker.ValueChanged += colorPicker_ValueChanged;
//
// btnForm
//
btnForm.Font = new System.Drawing.Font("Microsoft YaHei UI", 12F);
btnForm.Location = new System.Drawing.Point(38, 400);
btnForm.Name = "btnForm";
btnForm.Size = new System.Drawing.Size(99, 40);
btnForm.TabIndex = 1;
btnForm.Text = "窗体水印";
btnForm.Type = AntdUI.TTypeMini.Primary;
btnForm.Click += btnForm_Click;
//
// Watermark
//
AutoScaleMode = System.Windows.Forms.AutoScaleMode.Inherit;
Controls.Add(panel1);
Controls.Add(header1);
Font = new System.Drawing.Font("Microsoft YaHei UI", 12F);
Name = "Watermark";
Size = new System.Drawing.Size(835, 634);
panel1.ResumeLayout(false);
panel1.PerformLayout();
panel8.ResumeLayout(false);
ResumeLayout(false);
}
#endregion
private AntdUI.PageHeader header1;
private System.Windows.Forms.Panel panel1;
private AntdUI.Button btnForm;
private AntdUI.ColorPicker colorPicker;
private AntdUI.Label label6;
private AntdUI.Input inputContent;
private AntdUI.Input inputContent2;
private AntdUI.Label label1;
private AntdUI.Label label2;
private AntdUI.Slider trackOpacity;
private AntdUI.Label lblOpacity;
private AntdUI.Label lblRotate;
private AntdUI.Slider trackRotate;
private AntdUI.Label lblGap;
private AntdUI.Slider trackGap;
private AntdUI.Button btnPanel;
private AntdUI.Button btnClear;
private AntdUI.Panel panel8;
private AntdUI.Divider divider1;
private System.Windows.Forms.Label label7;
}
}

View File

@@ -0,0 +1,218 @@
// 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;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Demo.Controls
{
public partial class Watermark : UserControl
{
private AntdUI.FormWatermark? currentWatermark = null;
private Form form;
public Watermark(Form _form)
{
form = _form;
InitializeComponent();
inputContent2.Text = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
}
private void trackOpacity_ValueChanged(object sender, AntdUI.IntEventArgs e)
{
var opacity = e.Value / 100.0F;
lblOpacity.Text = $"透明度: {e.Value}%";
// 如果当前有水印,更新透明度
if (currentWatermark != null)
{
//CreateWatermark();
}
}
private void trackRotate_ValueChanged(object sender, AntdUI.IntEventArgs e)
{
lblRotate.Text = $"旋转角度: {e.Value}°";
// 如果当前有水印,更新旋转角度
if (currentWatermark != null)
{
//CreateWatermark();
}
}
private void trackGap_ValueChanged(object sender, AntdUI.IntEventArgs e)
{
lblGap.Text = $"间距: {e.Value}px";
// 如果当前有水印,更新间距
if (currentWatermark != null)
{
//CreateWatermark();
}
}
private void colorPicker_ValueChanged(object sender, AntdUI.ColorEventArgs e)
{
// 如果当前有水印,更新颜色
if (currentWatermark != null)
{
//CreateWatermark();
}
}
private void btnClear_Click(object sender, EventArgs e)
{
ClearWatermark();
}
private void ClearWatermark()
{
if (currentWatermark != null)
{
currentWatermark.Close();
currentWatermark = null;
//AntdUI.Message.info(form, "水印已清除");
}
}
private void btnForm_Click(object sender, EventArgs e)
{
// 清除现有水印
ClearWatermark();
try
{
var config = new AntdUI.Watermark.Config(form, inputContent.Text, inputContent2.Text)
{
Rotate = trackRotate.Value,
Gap = new int[] { trackGap.Value, trackGap.Value }
};
// 设置字体颜色透明度
var opacity = trackOpacity.Value / 100.0F;
var alpha = (int)(opacity * 255);
var selectedColor = colorPicker.Value;
config.Font.Color = Color.FromArgb(alpha, selectedColor.R, selectedColor.G, selectedColor.B);
currentWatermark = AntdUI.Watermark.open(config);
if (currentWatermark != null)
{
AntdUI.Message.success(form, "窗体水印创建成功!");
}
else
{
AntdUI.Message.error(form, "窗体水印创建失败");
}
}
catch (Exception ex)
{
AntdUI.Message.error(form, $"创建窗体水印时发生错误:{ex.Message}");
}
}
private void btnPanel_Click(object sender, EventArgs e)
{
// 清除现有水印
ClearWatermark();
try
{
var config = new AntdUI.Watermark.Config(panel8, inputContent.Text, inputContent2.Text)
{
Rotate = trackRotate.Value,
Gap = new int[] { trackGap.Value, trackGap.Value }
};
// 设置字体颜色透明度
var opacity = trackOpacity.Value / 100.0F;
var alpha = (int)(opacity * 255);
var selectedColor = colorPicker.Value;
config.Font.Color = Color.FromArgb(alpha, selectedColor.R, selectedColor.G, selectedColor.B);
currentWatermark = AntdUI.Watermark.open(config);
if (currentWatermark != null)
{
AntdUI.Message.success(form, "面板水印创建成功!");
}
else
{
AntdUI.Message.error(form, "面板水印创建失败");
}
}
catch (Exception ex)
{
AntdUI.Message.error(form, $"创建面板水印时发生错误:{ex.Message}");
}
}
private void header1_BackClick(object sender, EventArgs e)
{
// 清理水印
//ClearWatermark();
}
//private void CreateWatermark(Image? image = null)
//{
// // 清除现有水印
// ClearWatermark();
// try
// {
// var config = new AntdUI.Watermark.Config(form, inputContent.Text, inputContent2.Text)
// {
// Rotate = trackRotate.Value,
// Gap = new int[] { trackGap.Value, trackGap.Value + 10 },
// Image = image
// };
// // 设置字体颜色透明度
// var opacity = trackOpacity.Value / 100.0F;
// var alpha = (int)(opacity * 255);
// var selectedColor = colorPicker.Value;
// config.Font.Color = Color.FromArgb(alpha, selectedColor.R, selectedColor.G, selectedColor.B);
// currentWatermark = AntdUI.Watermark.open(config);
// if (currentWatermark != null)
// {
// var watermarkType = image != null ? "图片水印" : "文本水印";
// AntdUI.Message.success(form, $"{watermarkType}创建成功!");
// }
// else
// {
// AntdUI.Message.error(form, "水印创建失败,请检查窗体状态");
// }
// }
// catch (Exception ex)
// {
// AntdUI.Message.error(form, $"创建水印时发生错误:{ex.Message}");
// }
//}
}
}

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>

Binary file not shown.

View File

@@ -132,6 +132,15 @@ namespace Demo {
}
}
/// <summary>
/// 查找类似 &lt;svg viewBox=&quot;0 0 1024 1024&quot;&gt;&lt;path d=&quot;M830 194m-118 0a118 118 0 1 0 236 0 118 118 0 1 0-236 0Z&quot; fill=&quot;#91D5FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M840.8 716.8m-70.8 0a70.8 70.8 0 1 0 141.6 0 70.8 70.8 0 1 0-141.6 0Z&quot; fill=&quot;#91D5FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M287.8 470.8m-70.8 0a70.8 70.8 0 1 0 141.6 0 70.8 70.8 0 1 0-141.6 0Z&quot; fill=&quot;#91D5FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M595.6 428.6m-141.6 0a141.6 141.6 0 1 0 283.2 0 141.6 141.6 0 1 0-283.2 0Z&quot; fill=&quot;#1890FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M194 760m-118 0a118 118 0 1 0 236 0 118 118 0 1 0-236 0Z&quot; fill=&quot;#1890FF&quot;&gt;&lt; [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string Chart {
get {
return ResourceManager.GetString("Chart", resourceCulture);
}
}
/// <summary>
/// 查找类似 &lt;svg viewBox=&quot;0 0 104 75&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(-931.000000, -1722.000000)&quot;&gt;&lt;g id=&quot;CheckBox&quot; transform=&quot;translate(932.000000, 1722.000000)&quot;&gt;&lt;g id=&quot;3.DataEntry/Checkbox#&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;g id=&quot;7.Icon/control/checkbox/Checked-&quot;&gt;&lt;g id=&quot;icon/z/checkboxChecked-Copy&quot; fill=&quot;#1677FF&quot;&gt;&lt;rect id=&quot;box&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;14&quot; height=&quot;14&quot; rx=&quot;2&quot;&gt;&lt;/rect&gt;&lt;/g&gt;&lt;g id=&quot;check&quot; trans [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
@@ -509,5 +518,14 @@ namespace Demo {
return ResourceManager.GetString("Tree", resourceCulture);
}
}
/// <summary>
/// 查找类似 &lt;svg viewBox=&quot;0 0 194 116&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;defs&gt;&lt;rect id=&quot;path-1&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;194&quot; height=&quot;116&quot; rx=&quot;6.4000001&quot;&gt;&lt;/rect&gt;&lt;/defs&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(-521.000000, -5481.000000)&quot;&gt;&lt;g id=&quot;Ant-Design-5.0&quot; transform=&quot;translate(521.000000, 5481.000000)&quot;&gt;&lt;mask id=&quot;mask-2&quot; fill=&quot;white&quot;&gt;&lt;use xlink:href=&quot;#path-1&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;use id=&quot;蒙版&quot; fill=&quot;#1F1F1F&quot; xlink:href=&quot;#path-1&quot;&gt;&lt;/use&gt;&lt;text m [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string Watermark {
get {
return ResourceManager.GetString("Watermark", resourceCulture);
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -132,6 +132,15 @@ namespace Demo {
}
}
/// <summary>
/// 查找类似 &lt;svg viewBox=&quot;0 0 1024 1024&quot;&gt;&lt;path d=&quot;M830 194m-118 0a118 118 0 1 0 236 0 118 118 0 1 0-236 0Z&quot; fill=&quot;#91D5FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M840.8 716.8m-70.8 0a70.8 70.8 0 1 0 141.6 0 70.8 70.8 0 1 0-141.6 0Z&quot; fill=&quot;#91D5FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M287.8 470.8m-70.8 0a70.8 70.8 0 1 0 141.6 0 70.8 70.8 0 1 0-141.6 0Z&quot; fill=&quot;#91D5FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M595.6 428.6m-141.6 0a141.6 141.6 0 1 0 283.2 0 141.6 141.6 0 1 0-283.2 0Z&quot; fill=&quot;#1890FF&quot;&gt;&lt;/path&gt;&lt;path d=&quot;M194 760m-118 0a118 118 0 1 0 236 0 118 118 0 1 0-236 0Z&quot; fill=&quot;#1890FF&quot;&gt;&lt; [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string Chart {
get {
return ResourceManager.GetString("Chart", resourceCulture);
}
}
/// <summary>
/// 查找类似 &lt;svg viewBox=&quot;0 0 104 75&quot;&gt;&lt;g stroke=&quot;none&quot; stroke-width=&quot;1&quot; fill=&quot;none&quot; fill-rule=&quot;evenodd&quot;&gt;&lt;g transform=&quot;translate(-931.000000, -1722.000000)&quot; fill-rule=&quot;nonzero&quot;&gt;&lt;g transform=&quot;translate(932.000000, 1722.000000)&quot;&gt;&lt;g&gt;&lt;g fill=&quot;#1677FF&quot;&gt;&lt;rect x=&quot;0&quot; y=&quot;0&quot; width=&quot;14&quot; height=&quot;14&quot; rx=&quot;2&quot;/&gt;&lt;/g&gt;&lt;g transform=&quot;translate(2.625000, 2.625000)&quot;&gt;&lt;rect fill=&quot;#000000&quot; opacity=&quot;0&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;8.75&quot; height=&quot;8.75&quot;/&gt;&lt;path d=&quot;M8.28125,1.23046875 L7.59863281,1.23046875 C7.50292969,1.23046875 7.41210938,1.27441406 7.3535156 [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
@@ -509,5 +518,14 @@ namespace Demo {
return ResourceManager.GetString("Tree", resourceCulture);
}
}
/// <summary>
/// 查找类似 &lt;svg viewBox=&quot;0 0 196 118&quot; xmlns:xlink=&quot;http://www.w3.org/1999/xlink&quot;&gt;&lt;defs&gt;&lt;rect id=&quot;path-1&quot; x=&quot;0&quot; y=&quot;0&quot; width=&quot;194&quot; height=&quot;116&quot; rx=&quot;6.4000001&quot;&gt;&lt;/rect&gt;&lt;/defs&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(-520.000000, -5480.000000)&quot;&gt;&lt;g id=&quot;Ant-Design-5.0&quot; transform=&quot;translate(521.000000, 5481.000000)&quot;&gt;&lt;mask id=&quot;mask-2&quot; fill=&quot;white&quot;&gt;&lt;use xlink:href=&quot;#path-1&quot;&gt;&lt;/use&gt;&lt;/mask&gt;&lt;use id=&quot;蒙版&quot; stroke=&quot;#F0F0F0&quot; stroke-width=&quot;0.8&quot; fill=&quot;#FFFFFF&quot; fi [字符串的其余部分被截断]&quot;; 的本地化字符串。
/// </summary>
internal static string Watermark {
get {
return ResourceManager.GetString("Watermark", resourceCulture);
}
}
}
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,127 @@
// 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;
using System.ComponentModel;
using System.Drawing;
namespace AntdUI.Controls.Charts
{
/// <summary>
/// 图表数据点
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public class ChartDataPoint
{
/// <summary>
/// 标签
/// </summary>
[Description("标签"), Category("数据")]
public string? Label { get; set; }
/// <summary>
/// X轴值
/// </summary>
[Description("X轴值"), Category("数据")]
public double X { get; set; }
/// <summary>
/// Y轴值
/// </summary>
[Description("Y轴值"), Category("数据")]
public double Y { get; set; }
/// <summary>
/// 半径值(用于气泡图等)
/// </summary>
[Description("半径值"), Category("数据")]
public double Radius { get; set; }
/// <summary>
/// 颜色
/// </summary>
[Description("颜色"), Category("外观")]
public Color? Color { get; set; }
/// <summary>
/// 是否可见
/// </summary>
[Description("是否可见"), Category("行为"), DefaultValue(true)]
public bool Visible { get; set; } = true;
/// <summary>
/// 工具提示文本
/// </summary>
[Description("工具提示文本"), Category("行为")]
public string? Tooltip { get; set; }
/// <summary>
/// 创建数据点
/// </summary>
public ChartDataPoint() { }
/// <summary>
/// 创建数据点
/// </summary>
/// <param name="label">标签</param>
/// <param name="x">X轴值</param>
/// <param name="y">Y轴值</param>
public ChartDataPoint(string? label, double x, double y)
{
Label = label;
X = x;
Y = y;
}
/// <summary>
/// 创建数据点
/// </summary>
/// <param name="label">标签</param>
/// <param name="x">X轴值</param>
/// <param name="y">Y轴值</param>
/// <param name="radius">半径值</param>
public ChartDataPoint(string? label, double x, double y, double radius)
{
Label = label;
X = x;
Y = y;
Radius = radius;
}
/// <summary>
/// 创建数据点
/// </summary>
/// <param name="label">标签</param>
/// <param name="x">X轴值</param>
/// <param name="y">Y轴值</param>
/// <param name="color">颜色</param>
public ChartDataPoint(string? label, double x, double y, Color color)
{
Label = label;
X = x;
Y = y;
Color = color;
}
public override string ToString()
{
return $"({X}, {Y})";
}
}
}

View File

@@ -0,0 +1,179 @@
// 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;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Design;
namespace AntdUI.Controls.Charts
{
/// <summary>
/// 图表数据集
/// </summary>
[TypeConverter(typeof(ExpandableObjectConverter))]
public class ChartDataset
{
/// <summary>
/// 数据集标签
/// </summary>
[Description("数据集标签"), Category("数据")]
public string? Label { get; set; }
/// <summary>
/// 数据点集合
/// </summary>
[Description("数据点集合"), Category("数据")]
[Editor(typeof(Design.CollectionEditor), typeof(UITypeEditor))]
public List<ChartDataPoint> DataPoints { get; set; } = new List<ChartDataPoint>();
/// <summary>
/// 填充颜色
/// </summary>
[Description("填充颜色"), Category("外观")]
[Editor(typeof(Design.ColorEditor), typeof(UITypeEditor))]
public Color? FillColor { get; set; }
/// <summary>
/// 边框颜色
/// </summary>
[Description("边框颜色"), Category("外观")]
[Editor(typeof(Design.ColorEditor), typeof(UITypeEditor))]
public Color? BorderColor { get; set; }
/// <summary>
/// 边框宽度
/// </summary>
[Description("边框宽度"), Category("外观"), DefaultValue(1)]
public float BorderWidth { get; set; } = 1;
/// <summary>
/// 图例框填充颜色
/// </summary>
[Description("图例框填充颜色"), Category("外观")]
[Editor(typeof(Design.ColorEditor), typeof(UITypeEditor))]
public Color? LegendBoxFillColor { get; set; }
/// <summary>
/// 是否可见
/// </summary>
[Description("是否可见"), Category("行为"), DefaultValue(true)]
public bool Visible { get; set; } = true;
/// <summary>
/// Y轴格式
/// </summary>
[Description("Y轴格式"), Category("格式")]
public string? YFormat { get; set; }
/// <summary>
/// X轴格式
/// </summary>
[Description("X轴格式"), Category("格式")]
public string? XFormat { get; set; }
/// <summary>
/// 半径格式(用于气泡图等)
/// </summary>
[Description("半径格式"), Category("格式")]
public string? RadiusFormat { get; set; }
/// <summary>
/// 透明度
/// </summary>
[Description("透明度"), Category("外观"), DefaultValue(1.0f)]
public float Opacity { get; set; } = 1.0f;
/// <summary>
/// 创建数据集
/// </summary>
public ChartDataset() { }
/// <summary>
/// 创建数据集
/// </summary>
/// <param name="label">标签</param>
public ChartDataset(string? label)
{
Label = label;
}
/// <summary>
/// 创建数据集
/// </summary>
/// <param name="label">标签</param>
/// <param name="fillColor">填充颜色</param>
public ChartDataset(string? label, Color fillColor)
{
Label = label;
FillColor = fillColor;
}
/// <summary>
/// 添加数据点
/// </summary>
/// <param name="point">数据点</param>
public void AddPoint(ChartDataPoint point)
{
DataPoints.Add(point);
}
/// <summary>
/// 添加数据点
/// </summary>
/// <param name="label">标签</param>
/// <param name="x">X轴值</param>
/// <param name="y">Y轴值</param>
public void AddPoint(string? label, double x, double y)
{
DataPoints.Add(new ChartDataPoint(label, x, y));
}
/// <summary>
/// 添加数据点
/// </summary>
/// <param name="label">标签</param>
/// <param name="x">X轴值</param>
/// <param name="y">Y轴值</param>
/// <param name="radius">半径值</param>
public void AddPoint(string? label, double x, double y, double radius)
{
DataPoints.Add(new ChartDataPoint(label, x, y, radius));
}
/// <summary>
/// 清除所有数据点
/// </summary>
public void Clear()
{
DataPoints.Clear();
}
/// <summary>
/// 获取数据点数量
/// </summary>
public int Count => DataPoints.Count;
public override string ToString()
{
return $"{Label} ({Count} 个数据点)";
}
}
}

View File

@@ -0,0 +1,102 @@
// 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;
using System.Drawing;
namespace AntdUI.Controls.Charts
{
/// <summary>
/// 图表数据点点击事件参数
/// </summary>
public class ChartPointClickEventArgs : EventArgs
{
/// <summary>
/// 数据点
/// </summary>
public ChartDataPoint DataPoint { get; }
/// <summary>
/// 数据集索引
/// </summary>
public int DatasetIndex { get; }
/// <summary>
/// 数据点索引
/// </summary>
public int PointIndex { get; }
public ChartPointClickEventArgs(ChartDataPoint dataPoint, int datasetIndex = -1, int pointIndex = -1)
{
DataPoint = dataPoint;
DatasetIndex = datasetIndex;
PointIndex = pointIndex;
}
}
/// <summary>
/// 图表区域点击事件参数
/// </summary>
public class ChartAreaClickEventArgs : EventArgs
{
/// <summary>
/// 点击位置
/// </summary>
public Point Location { get; }
public ChartAreaClickEventArgs(Point location)
{
Location = location;
}
}
/// <summary>
/// 图表数据点悬停事件参数
/// </summary>
public class ChartPointHoverEventArgs : EventArgs
{
/// <summary>
/// 数据点
/// </summary>
public ChartDataPoint DataPoint { get; }
/// <summary>
/// 鼠标位置
/// </summary>
public Point Location { get; }
/// <summary>
/// 数据集索引
/// </summary>
public int DatasetIndex { get; }
/// <summary>
/// 数据点索引
/// </summary>
public int PointIndex { get; }
public ChartPointHoverEventArgs(ChartDataPoint dataPoint, Point location, int datasetIndex = -1, int pointIndex = -1)
{
DataPoint = dataPoint;
Location = location;
DatasetIndex = datasetIndex;
PointIndex = pointIndex;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,561 @@
// 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;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Windows.Forms;
using Microsoft.Win32;
namespace AntdUI
{
/// <summary>
/// 水印组件
/// 参考Ant Design Watermark组件https://ant.design/components/watermark-cn
/// </summary>
public class Watermark
{
/// <summary>
/// 水印配置类
/// </summary>
public class Config
{
/// <summary>
/// 目标控件
/// </summary>
public Control Target { get; set; }
/// <summary>
/// 水印文字内容
/// </summary>
public string Content { get; set; }
/// <summary>
/// 副内容
/// </summary>
public string SubContent { get; set; }
/// <summary>
/// 水印图片
/// </summary>
public Image? Image { get; set; }
/// <summary>
/// 水印宽度
/// </summary>
public int Width { get; set; } = 200;
/// <summary>
/// 水印高度
/// </summary>
public int Height { get; set; } = 100;
/// <summary>
/// 旋转角度
/// </summary>
public int Rotate { get; set; } = -22;
/// <summary>
/// Z轴层级
/// </summary>
public int ZIndex { get; set; } = 9;
/// <summary>
/// 水印间距 [x, y]
/// </summary>
public int[] Gap { get; set; } = new int[] { 100, 100 };
/// <summary>
/// 水印偏移量 [x, y]
/// </summary>
public int[] Offset { get; set; }
/// <summary>
/// 字体配置
/// </summary>
public FontConfig Font { get; set; } = new FontConfig();
/// <summary>
/// 是否启用
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// 是否为屏幕水印
/// </summary>
public bool IsScreen { get; set; } = false;
public Config(Control target, string content, string subContent = "")
{
Target = target;
Content = content;
SubContent = subContent;
Offset = new int[] { Gap[0] / 2, Gap[1] / 2 };
}
}
/// <summary>
/// 字体配置类
/// </summary>
public class FontConfig
{
/// <summary>
/// 字体颜色
/// </summary>
public Color Color { get; set; } = Color.FromArgb(38, 0, 0, 0);
/// <summary>
/// 字体大小
/// </summary>
public float FontSize { get; set; } = 14;
/// <summary>
/// 字体粗细
/// </summary>
public FontWeight FontWeight { get; set; } = FontWeight.Normal;
/// <summary>
/// 字体族
/// </summary>
public string FontFamily { get; set; } = "Microsoft YaHei";
/// <summary>
/// 字体样式
/// </summary>
public System.Drawing.FontStyle FontStyle { get; set; } = System.Drawing.FontStyle.Regular;
/// <summary>
/// 文本对齐方式
/// </summary>
public StringAlignment TextAlign { get; set; } = StringAlignment.Center;
}
/// <summary>
/// 字体粗细枚举
/// </summary>
public enum FontWeight
{
Normal = 400,
Light = 300,
Bold = 700
}
/// <summary>
/// 开启水印
/// </summary>
/// <param name="config">水印配置</param>
/// <returns>水印窗体</returns>
public static FormWatermark? open(Config config)
{
if (config?.Target == null || !config.Enabled)
return null;
try
{
// 创建新的水印窗体
var watermarkForm = new LayeredFormWatermark(config);
// 显示水印
watermarkForm.Show(config.Target);
return watermarkForm;
}
catch
{
return null;
}
}
/// <summary>
/// 开启水印(简化版本)
/// </summary>
/// <param name="target">目标控件</param>
/// <param name="content">水印内容</param>
/// <param name="subContent">副内容</param>
/// <returns>水印窗体</returns>
public static FormWatermark? open(Control target, string content, string subContent = "")
{
var config = new Config(target, content, subContent);
return open(config);
}
}
/// <summary>
/// 水印窗体接口
/// </summary>
public interface FormWatermark
{
/// <summary>
/// 关闭水印
/// </summary>
void Close();
}
/// <summary>
/// 水印窗体实现
/// </summary>
internal class LayeredFormWatermark : ILayeredFormOpacity, FormWatermark
{
Watermark.Config config;
internal bool topMost = false;
public LayeredFormWatermark(Watermark.Config _config) : base(255)
{
config = _config;
if (config.IsScreen)
{
// 屏幕水印
var screen = Screen.PrimaryScreen.Bounds;
SetSize(screen.Width, screen.Height);
SetLocation(screen.X, screen.Y);
topMost = true;
}
else
{
// 控件水印
UpdateWatermarkPosition();
}
// 监听目标控件的位置和大小变化
if (!config.IsScreen)
{
config.Target.LocationChanged += Target_LocationChanged;
config.Target.SizeChanged += Target_SizeChanged;
config.Target.VisibleChanged += Target_VisibleChanged;
// 监听父容器的移动事件
var parent = config.Target.Parent;
while (parent != null)
{
parent.LocationChanged += Parent_LocationChanged;
parent.SizeChanged += Parent_SizeChanged;
parent = parent.Parent;
}
// 监听Form的移动事件
var form = GetTopLevelForm(config.Target);
if (form != null)
{
form.LocationChanged += Form_LocationChanged;
form.SizeChanged += Form_SizeChanged;
}
}
// 监听系统事件
SystemEvents.DisplaySettingsChanged += SystemEvents_DisplaySettingsChanged;
}
private void Target_LocationChanged(object? sender, EventArgs e)
{
if (config.Target != null && !config.IsScreen)
{
UpdateWatermarkPosition();
}
}
private void Target_SizeChanged(object? sender, EventArgs e)
{
if (config.Target != null && !config.IsScreen)
{
UpdateWatermarkPosition();
}
}
private void Parent_LocationChanged(object? sender, EventArgs e)
{
if (config.Target != null && !config.IsScreen)
{
UpdateWatermarkPosition();
}
}
private void Parent_SizeChanged(object? sender, EventArgs e)
{
if (config.Target != null && !config.IsScreen)
{
UpdateWatermarkPosition();
}
}
private void Form_LocationChanged(object? sender, EventArgs e)
{
if (config.Target != null && !config.IsScreen)
{
UpdateWatermarkPosition();
}
}
private void Form_SizeChanged(object? sender, EventArgs e)
{
if (config.Target != null && !config.IsScreen)
{
UpdateWatermarkPosition();
}
}
private void UpdateWatermarkPosition()
{
if (config.Target != null && !config.IsScreen)
{
var rect = config.Target.RectangleToScreen(config.Target.ClientRectangle);
SetSize(rect.Width, rect.Height);
SetLocation(rect.X, rect.Y);
Print();
}
}
private Form? GetTopLevelForm(Control control)
{
while (control != null)
{
if (control is Form form)
{
return form;
}
control = control.Parent;
}
return null;
}
private void Target_VisibleChanged(object? sender, EventArgs e)
{
if (config.Target != null)
{
if (config.Target.Visible)
{
Show();
}
else
{
Hide();
}
}
}
private void SystemEvents_DisplaySettingsChanged(object? sender, EventArgs e)
{
if (config.IsScreen)
{
var screen = Screen.PrimaryScreen.Bounds;
SetSize(screen.Width, screen.Height);
SetLocation(screen.X, screen.Y);
Print();
}
}
public override Bitmap PrintBit()
{
var rect = TargetRectXY;
Bitmap original_bmp = new Bitmap(rect.Width, rect.Height);
using (var g = Graphics.FromImage(original_bmp))
{
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAlias;
if (!config.Enabled) return original_bmp;
var font = new Font(config.Font.FontFamily, config.Font.FontSize, config.Font.FontStyle);
var textColor = config.Font.Color;
var brush = new SolidBrush(textColor);
// 计算水印间距
var gapX = config.Gap[0];
var gapY = config.Gap[1];
var patternWidth = config.Width + gapX;
var patternHeight = config.Height + gapY;
// 计算起始偏移
var startX = config.Offset[0] % patternWidth;
var startY = config.Offset[1] % patternHeight;
// 绘制水印图案
for (int y = -startY; y < rect.Height; y += patternHeight)
{
for (int x = -startX; x < rect.Width; x += patternWidth)
{
DrawWatermarkItem(g, x, y, font, brush);
}
}
font.Dispose();
brush.Dispose();
}
return original_bmp;
}
private void DrawWatermarkItem(Graphics g, int x, int y, Font font, Brush brush)
{
// 保存当前状态
var state = g.Save();
// 设置旋转
if (config.Rotate != 0)
{
var centerX = x + config.Width / 2f;
var centerY = y + config.Height / 2f;
g.TranslateTransform(centerX, centerY);
g.RotateTransform(config.Rotate);
g.TranslateTransform(-centerX, -centerY);
}
// 绘制图片水印
if (config.Image != null)
{
DrawImageWatermark(g, x, y);
}
// 绘制文字水印
if (!string.IsNullOrEmpty(config.Content))
{
DrawTextWatermark(g, x, y, font, brush);
}
// 恢复状态
g.Restore(state);
}
private void DrawImageWatermark(Graphics g, int x, int y)
{
if (config.Image == null) return;
var imageWidth = Math.Min(config.Width, config.Image.Width);
var imageHeight = Math.Min(config.Height, config.Image.Height);
var drawX = x + (config.Width - imageWidth) / 2f;
var drawY = y + (config.Height - imageHeight) / 2f;
// 创建半透明图片
var colorMatrix = new ColorMatrix();
colorMatrix.Matrix33 = 0.15f; // 透明度
var imageAttributes = new ImageAttributes();
imageAttributes.SetColorMatrix(colorMatrix, ColorMatrixFlag.Default, ColorAdjustType.Bitmap);
g.DrawImage(config.Image,
new Rectangle((int)drawX, (int)drawY, (int)imageWidth, (int)imageHeight),
0, 0, config.Image.Width, config.Image.Height,
GraphicsUnit.Pixel, imageAttributes);
imageAttributes.Dispose();
}
private void DrawTextWatermark(Graphics g, int x, int y, Font font, Brush brush)
{
if (string.IsNullOrEmpty(config.Content)) return;
var format = new StringFormat
{
Alignment = config.Font.TextAlign,
LineAlignment = StringAlignment.Center
};
// 计算文字区域
var contentHeight = (float)config.Height;
var subContentHeight = 0f;
var spacing = 4f; // 主内容和副内容之间的间距
if (!string.IsNullOrEmpty(config.SubContent))
{
// 如果有副内容,计算实际需要的空间
var subFont = new Font(config.Font.FontFamily, config.Font.FontSize * 0.8f, config.Font.FontStyle);
// 测量主内容文字高度
var mainSize = g.MeasureString(config.Content, font, config.Width, format);
// 测量副内容文字高度
var subSize = g.MeasureString(config.SubContent, subFont, config.Width, format);
// 计算总高度
var totalTextHeight = mainSize.Height + spacing + subSize.Height;
// 如果总高度超过水印高度,则按比例缩放
if (totalTextHeight > config.Height)
{
var scale = config.Height / totalTextHeight;
contentHeight = mainSize.Height * scale;
subContentHeight = subSize.Height * scale;
spacing = spacing * scale;
}
else
{
contentHeight = mainSize.Height;
subContentHeight = subSize.Height;
}
subFont.Dispose();
}
// 计算垂直居中位置
var totalHeight = contentHeight + (string.IsNullOrEmpty(config.SubContent) ? 0 : spacing + subContentHeight);
var startY = y + (config.Height - totalHeight) / 2f;
// 绘制主内容
var mainRect = new RectangleF((float)x, startY, (float)config.Width, contentHeight);
g.DrawString(config.Content, font, brush, mainRect, format);
// 绘制副内容
if (!string.IsNullOrEmpty(config.SubContent))
{
var subFont = new Font(config.Font.FontFamily, config.Font.FontSize * 0.8f, config.Font.FontStyle);
var subRect = new RectangleF((float)x, startY + contentHeight + spacing, (float)config.Width, subContentHeight);
g.DrawString(config.SubContent, subFont, brush, subRect, format);
subFont.Dispose();
}
format.Dispose();
}
public new void Close()
{
// 移除事件监听
if (config.Target != null && !config.IsScreen)
{
config.Target.LocationChanged -= Target_LocationChanged;
config.Target.SizeChanged -= Target_SizeChanged;
config.Target.VisibleChanged -= Target_VisibleChanged;
// 移除父容器的事件监听
var parent = config.Target.Parent;
while (parent != null)
{
parent.LocationChanged -= Parent_LocationChanged;
parent.SizeChanged -= Parent_SizeChanged;
parent = parent.Parent;
}
// 移除Form的事件监听
var form = GetTopLevelForm(config.Target);
if (form != null)
{
form.LocationChanged -= Form_LocationChanged;
form.SizeChanged -= Form_SizeChanged;
}
}
SystemEvents.DisplaySettingsChanged -= SystemEvents_DisplaySettingsChanged;
base.Close();
}
public override string name => "Watermark";
}
}

View File

@@ -0,0 +1,48 @@
// 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;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.Drawing.Design;
using System.Windows.Forms.Design;
namespace AntdUI.Design
{
public class CollectionEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext? context) => UITypeEditorEditStyle.Modal;
public override object? EditValue(ITypeDescriptorContext? context, IServiceProvider provider, object? value)
{
var service = provider.GetService(typeof(IWindowsFormsEditorService));
if (service is IWindowsFormsEditorService editorService)
{
if (value is IList list)
{
// Use the standard .NET CollectionEditor for IList collections
var collectionEditor = new System.ComponentModel.Design.CollectionEditor(list.GetType());
return collectionEditor.EditValue(context, provider, value);
}
}
return value;
}
}
}

View File

@@ -0,0 +1,92 @@
// 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
namespace AntdUI
{
/// <summary>
/// 图表类型
/// </summary>
public enum TChartType
{
/// <summary>
/// 面积图 - 绘制数据点并强调累积总量
/// </summary>
Area,
/// <summary>
/// 柱状图 - 用柱状图直观比较不同类别的数据
/// </summary>
Bar,
/// <summary>
/// 气泡图 - 用不同大小的圆圈表示数据点
/// </summary>
Bubble,
/// <summary>
/// 环形图 - 以环形饼图显示数据
/// </summary>
Doughnut,
/// <summary>
/// 水平柱状图 - 使用水平柱状图提供另一种视角
/// </summary>
HorizontalBar,
/// <summary>
/// 折线图 - 连接数据点以显示趋势和模式
/// </summary>
Line,
/// <summary>
/// 饼图 - 将数据表示为传统饼图的切片
/// </summary>
Pie,
/// <summary>
/// 极坐标面积图 - 径向排列数据点以获得独特视图
/// </summary>
PolarArea,
/// <summary>
/// 雷达图 - 在雷达图上呈现多变量数据点
/// </summary>
Radar,
/// <summary>
/// 散点图 - 散点数据以识别关系
/// </summary>
Scatter,
/// <summary>
/// 样条曲线图 - 平滑曲线无缝连接数据点
/// </summary>
Spline,
/// <summary>
/// 样条面积图 - 将样条曲线与面积图混合以获得影响
/// </summary>
SplineArea,
/// <summary>
/// 堆叠柱状图 - 堆叠数据类别以获得整体表示
/// </summary>
StackedBar,
/// <summary>
/// 堆叠水平柱状图 - 水平堆叠柱状图以获得引人入胜的可视化效果
/// </summary>
StackedHorizontalBar,
/// <summary>
/// 阶梯面积图 - 创建阶梯面积图以显示明显的趋势
/// </summary>
SteppedArea,
/// <summary>
/// 阶梯线图 - 用阶梯线段说明数据变化
/// </summary>
SteppedLine
}
}