Commit 6fa58cee 顾剑亮

upload

1 个父辈 a2a230ca
正在显示 209 个修改的文件 包含 12286 行增加45 行删除
{
"CurrentProjectSetting": null
}
\ No newline at end of file
此文件类型无法预览
{
"ExpandedNodes": [
""
],
"PreviewInSolutionExplorer": false
}
\ No newline at end of file
此文件类型无法预览

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16
VisualStudioVersion = 16.0.30523.141
VisualStudioVersion = 16.0.31112.23
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApp1", "WindowsFormsApp1\WindowsFormsApp1.csproj", "{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceControl", "FaceControl\FaceControl.csproj", "{BB46377E-CC9F-4AC2-9367-87503B59EFE7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{543499F4-8839-47F3-AC66-27627B259238}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
......@@ -11,15 +13,19 @@ Global
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Release|Any CPU.Build.0 = Release|Any CPU
{BB46377E-CC9F-4AC2-9367-87503B59EFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{BB46377E-CC9F-4AC2-9367-87503B59EFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU
{BB46377E-CC9F-4AC2-9367-87503B59EFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU
{BB46377E-CC9F-4AC2-9367-87503B59EFE7}.Release|Any CPU.Build.0 = Release|Any CPU
{543499F4-8839-47F3-AC66-27627B259238}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{543499F4-8839-47F3-AC66-27627B259238}.Debug|Any CPU.Build.0 = Debug|Any CPU
{543499F4-8839-47F3-AC66-27627B259238}.Release|Any CPU.ActiveCfg = Release|Any CPU
{543499F4-8839-47F3-AC66-27627B259238}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {B0C8A353-FACB-4930-9D25-C6ECB846F05A}
SolutionGuid = {B1F3BB0E-683B-4A34-82B4-BC20F5468010}
EndGlobalSection
EndGlobal
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
namespace Asa.FaceControl
{
public static class ImageConvert
{
public static Bitmap ToDisabledGray(Bitmap bmp, int lower = 50)
{
if (bmp == null) return null;
int channel;
if (bmp.PixelFormat == PixelFormat.Format24bppRgb)
channel = 3;
else if (bmp.PixelFormat == PixelFormat.Format32bppArgb)
channel = 4;
else
return bmp;
int width = bmp.Width;
int height = bmp.Height;
int widthByte = width * channel;
BitmapData data1 = bmp.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, bmp.PixelFormat);
byte[] buffer = new byte[data1.Stride * height];
int stride = data1.Stride;
System.Runtime.InteropServices.Marshal.Copy(data1.Scan0, buffer, 0, buffer.Length);
bmp.UnlockBits(data1);
byte r, g, b;
for (int i = 0; i < height; i++)
{
for (int j = 0; j < widthByte; j += channel)
{
r = buffer[i * stride + j];
g = buffer[i * stride + j + 1];
b = buffer[i * stride + j + 2];
int gray = (r + g + b) / 3 - lower;
if (gray < 0) gray = 0;
buffer[i * stride + j] = (byte)gray;
buffer[i * stride + j + 1] = (byte)gray;
buffer[i * stride + j + 2] = (byte)gray;
}
}
Bitmap image = new(width, height, bmp.PixelFormat);
BitmapData data2 = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadWrite, image.PixelFormat);
System.Runtime.InteropServices.Marshal.Copy(buffer, 0, data2.Scan0, buffer.Length);
image.UnlockBits(data2);
return image;
}
}
}

namespace Asa.FaceControl
{
partial class ControlBase
{
/// <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()
{
this.SuspendLayout();
//
// ControlBase
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.DoubleBuffered = true;
this.Name = "ControlBase";
this.Size = new System.Drawing.Size(90, 45);
this.Load += new System.EventHandler(this.ControlBase_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.ControlBase_Paint);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.ControlBase_MouseDown);
this.MouseEnter += new System.EventHandler(this.ControlBase_MouseEnter);
this.MouseLeave += new System.EventHandler(this.ControlBase_MouseLeave);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.ControlBase_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.ControlBase_MouseUp);
this.Resize += new System.EventHandler(this.ControlBase_Resize);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Asa.FaceControl
{
public partial class ControlBase : UserControl
{
//=====属性变量=====
private int _borderWidth = 2;
private ControlShape _faceShape = ControlShape.Rectangle;
//=====私有变量=====
private readonly Dictionary<ControlShape, Action> dicShape;
private bool borderEnterChanged;
//=====子类变量=====
internal RectangleF borderRect;
internal GraphicsPath borderPath;
internal IFaceThemeColor theme;
internal bool borderEnter;
internal bool mouseLeftDown;
internal bool mouseRightDown;
internal StringFormat stringFormat = new(StringFormatFlags.NoClip);
internal readonly SolidBrush BRUSH_DISABLED;
public ControlBase()
{
InitializeComponent();
theme = new DarkThemeColor();
BRUSH_DISABLED = new SolidBrush(theme.DISABLED);
AutoScaleMode = AutoScaleMode.None;
BackColor = theme.BACK;
ForeColor = theme.FORE;
Padding = new Padding(3);
dicShape = new Dictionary<ControlShape, Action>
{
{ ControlShape.Rectangle, ShapeRectangle },
{ ControlShape.RoundRectangle, ShapeRoundRectangle },
{ ControlShape.Ellipse, ShapeEllipse },
{ ControlShape.EllipseRectangle, ShapeEllipseRectangle },
{ ControlShape.Circle, ShapeCircle }
};
}
//=====公共方法=====
public Bitmap ToImage()
{
IntPtr hSrce = API.GetWindowDC(Handle);
IntPtr hDest = API.CreateCompatibleDC(hSrce);
IntPtr hBmp = API.CreateCompatibleBitmap(hSrce, Width, Height);
IntPtr hOldBmp = API.SelectObject(hDest, hBmp);
if (API.BitBlt(hDest, 0, 0, Width, Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
{
Bitmap bmp = Image.FromHbitmap(hBmp);
API.SelectObject(hDest, hOldBmp);
API.DeleteObject(hBmp);
API.DeleteDC(hDest);
API.ReleaseDC(Handle, hSrce);
return bmp;
}
return null;
}
//=====子类方法=====
protected virtual void CalcSize()
{
//边框位置
float x = _borderWidth / 2f;
float y = _borderWidth / 2f;
float width = ClientSize.Width - _borderWidth - 1;
float height = ClientSize.Height - _borderWidth - 1;
borderRect = new RectangleF(x, y, width, height);
//边框路径
borderPath = new GraphicsPath();
dicShape[_faceShape].Invoke();
}
protected virtual void DrawEnabled(Graphics g)
{
borderEnterChanged = borderEnter;
}
protected virtual void DrawDisabled(Graphics g)
{
}
public virtual void LostFocused()
{
}
//=====事件=====
[Browsable(true)]
public new event EventHandler TextChanged;
//=====属性=====
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int BorderWidth
{
get => _borderWidth;
set
{
_borderWidth = value > 0 ? value : 0;
CalcSize();
Refresh();
}
}
//[Browsable(true)]
//public override Color BackColor
//{
// get => base.BackColor;
// set
// {
// base.BackColor = value;
// Refresh();
// }
//}
//[Browsable(true)]
//public override Color ForeColor
//{
// get => base.ForeColor;
// set
// {
// base.ForeColor = value;
// Refresh();
// }
//}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new ControlShape BorderStyle
{
get => _faceShape;
set
{
_faceShape = value;
CalcSize();
Refresh();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Font Font
{
get => base.Font;
set
{
base.Font = value;
CalcSize();
Refresh();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get => base.Text;
set
{
base.Text = value;
CalcSize();
Refresh();
TextChanged?.Invoke(this, new EventArgs());
}
}
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new string AccessibleDescription { set => base.AccessibleDescription = value; get => base.AccessibleDescription; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new string AccessibleName { set => base.AccessibleName = value; get => base.AccessibleName; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new AccessibleRole AccessibleRole { set => base.AccessibleRole = value; get => base.AccessibleRole; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new bool AllowDrop { set => base.AllowDrop = value; get => base.AllowDrop; }
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
public new AutoScaleMode AutoScaleMode { set => base.AutoScaleMode = AutoScaleMode.None; get => AutoScaleMode.None; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new bool AutoScroll { get => base.AutoScroll; set => base.AutoScroll = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new Size AutoScrollMargin { get => base.AutoScrollMargin; set => base.AutoScrollMargin = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new Size AutoScrollMinSize { get => base.AutoScrollMinSize; set => base.AutoScrollMinSize = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new bool AutoSize { get => base.AutoSize; set => base.AutoSize = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new AutoSizeMode AutoSizeMode { get => base.AutoSizeMode; set => base.AutoSizeMode = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new AutoValidate AutoValidate { get => base.AutoValidate; set => base.AutoValidate = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new Image BackgroundImage { get => base.BackgroundImage; set => base.BackgroundImage = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new ImageLayout BackgroundImageLayout { get => base.BackgroundImageLayout; set => base.BackgroundImageLayout = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new bool CausesValidation { get => base.CausesValidation; set => base.CausesValidation = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new ContextMenuStrip ContextMenuStrip { get => base.ContextMenuStrip; set => base.ContextMenuStrip = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new Cursor Cursor { get => base.Cursor; set => base.Cursor = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new bool DoubleBuffered { get => base.DoubleBuffered; set => base.DoubleBuffered = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new ImeMode ImeMode { get => base.ImeMode; set => base.ImeMode = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new Size MaximumSize { get => base.MaximumSize; set => base.MaximumSize = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new Size MinimumSize { get => base.MinimumSize; set => base.MinimumSize = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new RightToLeft RightToLeft { get => base.RightToLeft; set => base.RightToLeft = value; }
//[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
//public new bool UseWaitCursor { get => base.UseWaitCursor; set => base.UseWaitCursor = value; }
private void ShapeRectangle()
{
borderPath.AddRectangle(borderRect);
}
private void ShapeRoundRectangle()
{
float n = borderRect.Height / 8f;
borderPath.AddLine(borderRect.X + n, borderRect.Y, borderRect.Right - n, borderRect.Y);
borderPath.AddArc(borderRect.Right - n - n, borderRect.Y, n + n, n + n, 270, 90);
borderPath.AddLine(borderRect.Right, borderRect.Y + n, borderRect.Right, borderRect.Bottom - n);
borderPath.AddArc(borderRect.Right - n - n, borderRect.Bottom - n - n, n + n, n + n, 0, 90);
borderPath.AddLine(borderRect.Right - n, borderRect.Bottom, borderRect.X + n, borderRect.Bottom);
borderPath.AddArc(borderRect.X, borderRect.Bottom - n - n, n + n, n + n, 90, 90);
borderPath.AddLine(borderRect.X, borderRect.Bottom - n, borderRect.X, borderRect.Y + n);
borderPath.AddArc(borderRect.X, borderRect.Y, n + n, n + n, 180, 90);
}
private void ShapeEllipse()
{
borderPath.AddEllipse(borderRect);
}
private void ShapeEllipseRectangle()
{
float n = borderRect.Height / 2f;
borderPath.AddLine(borderRect.X + n, borderRect.Y, borderRect.Right - n, borderRect.Y);
borderPath.AddArc(borderRect.Right - n - n, borderRect.Y, n + n, n + n, 270, 180);
borderPath.AddLine(borderRect.Right - n, borderRect.Bottom, borderRect.X + n, borderRect.Bottom);
borderPath.AddArc(borderRect.X, borderRect.Y, n + n, n + n, 90, 180);
}
private void ShapeCircle()
{
if (borderRect.Width > borderRect.Height)
borderPath.AddEllipse((borderRect.Width - borderRect.Height) / 2f, borderRect.Y, borderRect.Height, borderRect.Height);
else
borderPath.AddEllipse(borderRect.X, (borderRect.Height - borderRect.Width) / 2f, borderRect.Width, borderRect.Width);
}
private void DrawBorder(Graphics g)
{
//边框以外的部分
Region reg = new(ClientRectangle);
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(theme.BACK), reg);
//边框
if (_borderWidth > 0)
{
Color color = theme.DISABLED;
if (Enabled)
color = borderEnter ? theme.BORDER_ENTER : theme.BORDER_LEAVE;
Pen pen = new(color, _borderWidth);
g.DrawPath(pen, borderPath);
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) //禁掉清除背景消息
return;
base.WndProc(ref m);
}
private void ControlBase_Load(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void ControlBase_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void ControlBase_Paint(object sender, PaintEventArgs e)
{
BufferedGraphicsContext current = BufferedGraphicsManager.Current;
BufferedGraphics bg = current.Allocate(e.Graphics, e.ClipRectangle);
Graphics g = bg.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.Clear(BackColor); //背景
if (Enabled)
DrawEnabled(g);
else
DrawDisabled(g);
DrawBorder(g);
bg.Render();
bg.Dispose();
}
private void ControlBase_MouseEnter(object sender, EventArgs e)
{
//cursorInside = true;
}
private void ControlBase_MouseLeave(object sender, EventArgs e)
{
//cursorInside = false;
borderEnter = false;
Refresh();
}
private void ControlBase_MouseDown(object sender, MouseEventArgs e)
{
if (TopLevelControl is FormBase frm)
frm.SetLostFocus(frm, Handle);
if (e.Button == MouseButtons.Left)
{
mouseLeftDown = true;
mouseRightDown = false;
}
else if (e.Button == MouseButtons.Right)
{
mouseLeftDown = false;
mouseRightDown = true;
}
Refresh();
}
private void ControlBase_MouseUp(object sender, MouseEventArgs e)
{
mouseLeftDown = false;
mouseRightDown = false;
Refresh();
}
private void ControlBase_MouseMove(object sender, MouseEventArgs e)
{
borderEnter = borderPath.IsVisible(e.Location);
if (borderEnterChanged != borderEnter)
Refresh();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FormBase
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.SuspendLayout();
//
// FormBase
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(457, 369);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "FormBase";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "FormBase";
this.Load += new System.EventHandler(this.FormBase_Load);
this.Paint += new System.Windows.Forms.PaintEventHandler(this.FormBase_Paint);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FormBase_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FormBase_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FormBase_MouseUp);
this.Resize += new System.EventHandler(this.FormBase_Resize);
this.ResumeLayout(false);
}
#endregion
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Asa.FaceControl
{
public partial class FormBase : Form
{
//=====属性变量=====
private int _borderWidth = 2;
private Bitmap _iconBmp = null;
private Font _titleFont = new("宋体", 12f);
private int _titleHeight = 36;
//=====私有变量=====
private CursorPlace place;
private RectangleF borderRect;
private RectangleF iconRect;
private RectangleF titleTextRect;
private Rectangle windowRect;
private Bitmap iconGrayBmp;
private bool formActivated = true;
private readonly SolidBrush BRUSH_TEXT;
private readonly SolidBrush BRUSH_TEXT_DISABLED;
//=====子类变量=====
internal IFaceThemeColor theme;
public FormBase()
{
InitializeComponent();
theme = new DarkThemeColor();
BRUSH_TEXT = new SolidBrush(theme.FORE);
BRUSH_TEXT_DISABLED = new SolidBrush(theme.DISABLED);
AutoScaleMode = AutoScaleMode.None;
BackColor = theme.BACK;
ForeColor = theme.FORE;
Padding = new Padding(6 + _borderWidth);
_iconBmp = base.Icon.ToBitmap();
iconGrayBmp = ImageConvert.ToDisabledGray(_iconBmp, 0);
Activated += FormBase_Activated;
Deactivate += FormBase_Deactivate;
}
//=====公共方法=====
public Bitmap ToImage()
{
IntPtr hSrce = API.GetWindowDC(Handle);
IntPtr hDest = API.CreateCompatibleDC(hSrce);
IntPtr hBmp = API.CreateCompatibleBitmap(hSrce, Width, Height);
IntPtr hOldBmp = API.SelectObject(hDest, hBmp);
if (API.BitBlt(hDest, 0, 0, Width, Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
{
Bitmap bmp = Image.FromHbitmap(hBmp);
API.SelectObject(hDest, hOldBmp);
API.DeleteObject(hBmp);
API.DeleteDC(hDest);
API.ReleaseDC(Handle, hSrce);
return bmp;
}
return null;
}
public void Maximize()
{
windowRect = new Rectangle(Location, Size);
Screen screen = Screen.FromControl(this);
Top = screen.WorkingArea.Top;
Left = screen.WorkingArea.Left;
Width = screen.WorkingArea.Width;
Height = screen.WorkingArea.Height;
IsMaximized = true;
}
public void Restore()
{
Left = windowRect.Left;
Top = windowRect.Top;
Width = windowRect.Width;
Height = windowRect.Height;
IsMaximized = false;
}
//=====子类方法=====
protected virtual void CalcSize()
{
//边框位置
float x = _borderWidth / 2f;
float y = _borderWidth / 2f;
float width = ClientSize.Width - _borderWidth - 1;
float height = ClientSize.Height - _borderWidth - 1;
borderRect = new RectangleF(x, y, width, height);
//titleRect = new RectangleF(x, y, width, _titleHeight);
//标题文本位置
using Graphics g = CreateGraphics();
SizeF sf = g.MeasureString(Text, _titleFont);
x = (Width - sf.Width) / 2f;
y = (_titleHeight - sf.Height) / 2f;
titleTextRect = new RectangleF(x, y, sf.Width, sf.Height);
//图标位置
if (_iconBmp != null)
{
height = _titleHeight - 6;
width = _iconBmp.Width * height / _iconBmp.Height;
iconRect = new RectangleF(borderRect.X + 3, borderRect.Y + 3, width, height);
}
}
protected virtual void DrawEnabled(Graphics g)
{
}
protected virtual void DrawDisabled(Graphics g)
{
}
//=====事件=====
[Browsable(true)]
public new event EventHandler TextChanged;
[Browsable(true)]
public event EventHandler BorderWidthChanged;
//=====属性=====
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int BorderWidth
{
get => _borderWidth;
set
{
_borderWidth = value > 0 ? value : 0;
Padding = new Padding(6 + _borderWidth);
CalcSize();
Refresh();
BorderWidthChanged?.Invoke(this, new EventArgs());
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get => base.Text;
set
{
base.Text = value;
CalcSize();
Refresh();
TextChanged?.Invoke(this, new EventArgs());
}
}
[Browsable(true), Category(""), Description("图标"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new Bitmap Icon
{
get => _iconBmp;
set
{
_iconBmp = value;
iconGrayBmp = ImageConvert.ToDisabledGray(_iconBmp, 0);
CalcSize();
Refresh();
}
}
[Browsable(true), Category("Title"), Description("标题字体")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Font TitleFont
{
get => _titleFont;
set
{
_titleFont = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("Title"), Description("标题栏高度"), DefaultValue(36)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int TitleHeight
{
get => _titleHeight;
set
{
_titleHeight = value;
CalcSize();
Refresh();
}
}
[Browsable(false)]
public new Font Font { get; set; }
internal bool IsMaximized { get; set; } = false;
internal bool CanResize { get; set; } = true;
public void SetLostFocus(Control ctl, IntPtr ptr)
{
foreach (Control list in ctl.Controls)
{
if (list is ControlBase control)
{
if (control.Handle == ptr) continue;
control.LostFocused();
}
else if (list is PanelBase)
{
SetLostFocus(list, ptr);
}
}
}
private void DrawBorder(Graphics g)
{
if (_borderWidth > 0)
{
Pen borderPen = new(formActivated ? theme.BORDER_ENTER : theme.BORDER_LEAVE, _borderWidth);
g.DrawRectangle(borderPen, borderRect.X, borderRect.Y, borderRect.Width, borderRect.Height);
}
}
private void DrawTitle(Graphics g)
{
if (_iconBmp != null)
g.DrawImage(formActivated ? _iconBmp : iconGrayBmp, iconRect, new RectangleF(0, 0, _iconBmp.Width, _iconBmp.Height), GraphicsUnit.Pixel);
if (formActivated)
g.DrawString(Text, _titleFont, BRUSH_TEXT, titleTextRect);
else
g.DrawString(Text, _titleFont, BRUSH_TEXT_DISABLED, titleTextRect);
}
private void ChangeMouseCursor(Point pt)
{
int space = 6;
Cursor cursor = Cursors.Default;
if (CanResize)
{
if (pt.X <= space && pt.Y <= space) //左上角
{
cursor = Cursors.SizeNWSE;
place = CursorPlace.LeftTop;
}
else if (pt.X > space && pt.X < Width - space && pt.Y <= space) //上边
{
cursor = Cursors.SizeNS;
place = CursorPlace.Top;
}
else if (pt.X >= Width - space && pt.Y <= space) //右上角
{
cursor = Cursors.SizeNESW;
place = CursorPlace.RightTop;
}
else if (pt.X <= space && pt.Y > space && pt.Y < Height - space) //左边
{
cursor = Cursors.SizeWE;
place = CursorPlace.Left;
}
else if (pt.X >= Width - space && pt.Y > space && pt.Y < Height - space) //右边
{
cursor = Cursors.SizeWE;
place = CursorPlace.Right;
}
else if (pt.X <= space && pt.Y >= Height - space) //左下角
{
cursor = Cursors.SizeNESW;
place = CursorPlace.LeftBottom;
}
else if (pt.X > space && pt.X < Width - space && pt.Y >= Height - space) //下边
{
cursor = Cursors.SizeNS;
place = CursorPlace.Bottom;
}
else if (pt.X >= Width - space - space && pt.Y >= Height - space - space) //右下角
{
cursor = Cursors.SizeNWSE;
place = CursorPlace.RightBottom;
}
else if (pt.X > space && pt.X < Width - space && pt.Y > space && pt.Y < _titleHeight) //标题栏
{
cursor = Cursors.Default;
place = CursorPlace.Inside;
}
else if (pt.X > space && pt.X < Width - space && pt.Y > _titleHeight && pt.Y < Height - space) //中间
{
cursor = Cursors.Default;
place = CursorPlace.None;
}
}
else
{
if (pt.X > space && pt.X < Width - space && pt.Y > space && pt.Y < _titleHeight) //标题栏
{
cursor = Cursors.Default;
place = CursorPlace.Inside;
}
else
{
cursor = Cursors.Default;
place = CursorPlace.None;
}
}
if (cursor != Cursor)
Cursor = cursor;
}
private void ChangeFormSize()
{
if (place == CursorPlace.None)
return;
API.ReleaseCapture();
API.SendMessage(Handle, API.WM_SYSCOMMAND, (int)place, 0);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) //禁掉清除背景消息
return;
base.WndProc(ref m);
}
private void FormBase_Load(object sender, EventArgs e)
{
CalcSize();
Refresh();
//居中屏幕
if (!DesignMode)
{
Screen screen = Screen.FromControl(this);
int x = (screen.WorkingArea.Width - Width) / 2;
int y = (screen.WorkingArea.Height - Height) / 2;
Location = new Point(x, y);
}
windowRect = new Rectangle(Location, Size);
Language.SetLanguage(this);
}
private void FormBase_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void FormBase_Paint(object sender, PaintEventArgs e)
{
BufferedGraphicsContext current = BufferedGraphicsManager.Current;
BufferedGraphics bg = current.Allocate(e.Graphics, e.ClipRectangle);
Graphics g = bg.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.Clear(BackColor); //背景
DrawTitle(g);
DrawBorder(g);
bg.Render();
bg.Dispose();
}
private void FormBase_MouseDown(object sender, MouseEventArgs e)
{
SetLostFocus(this, Handle);
if (e.Button == MouseButtons.Left)
{
if (!IsMaximized)
ChangeFormSize();
}
}
private void FormBase_MouseUp(object sender, MouseEventArgs e)
{
}
private void FormBase_MouseMove(object sender, MouseEventArgs e)
{
if (MouseButtons == MouseButtons.None)
{
if (!IsMaximized) //不是最大化
ChangeMouseCursor(e.Location);
}
}
private void FormBase_Deactivate(object sender, EventArgs e)
{
formActivated = false;
Refresh();
}
private void FormBase_Activated(object sender, EventArgs e)
{
formActivated = true;
Refresh();
}
private enum CursorPlace : int
{
None = 0,
Left = 0xF001,
Top = 0xF003,
Right = 0xF002,
Bottom = 0xF006,
LeftTop = 0xF004,
RightTop = 0xF005,
LeftBottom = 0xF007,
RightBottom = 0xF008,
Inside = API.SC_MOVE + API.HTCAPTION
}
}
}
<?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>
\ No newline at end of file
namespace WindowsFormsApp1

namespace Asa.FaceControl
{
partial class Form1
partial class PanelBase
{
/// <summary>
/// 必需的设计器变量。
......@@ -20,7 +21,7 @@
base.Dispose(disposing);
}
#region Windows 窗体设计器生成的代码
#region 组件设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
......@@ -28,13 +29,15 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 450);
this.Text = "Form1";
this.SuspendLayout();
//
// PanelBase
//
this.Name = "PanelBase";
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Asa.FaceControl
{
public partial class PanelBase : Panel
{
//=====属性变量=====
private int _borderWidth = 2;
private ControlShape _faceShape = ControlShape.Rectangle;
//=====私有变量=====
private readonly Dictionary<ControlShape, Action> dicShape;
//private bool borderEnterChanged;
//=====子类变量=====
internal RectangleF borderRect;
internal GraphicsPath borderPath;
internal IFaceThemeColor theme;
//internal bool borderEnter;
internal bool mouseLeftDown;
internal bool mouseRightDown;
internal StringFormat stringFormat = new(StringFormatFlags.NoClip);
public PanelBase()
{
InitializeComponent();
theme = new DarkThemeColor();
BackColor = theme.BACK;
ForeColor = theme.FORE;
Padding = new Padding(3);
dicShape = new Dictionary<ControlShape, Action>
{
{ ControlShape.Rectangle, ShapeRectangle },
{ ControlShape.RoundRectangle, ShapeRoundRectangle },
{ ControlShape.Ellipse, ShapeEllipse },
{ ControlShape.EllipseRectangle, ShapeEllipseRectangle },
{ ControlShape.Circle, ShapeCircle }
};
Resize += ControlBase_Resize;
Paint += ControlBase_Paint;
//MouseEnter += ControlBase_MouseEnter;
//MouseLeave += ControlBase_MouseLeave;
MouseDown += ControlBase_MouseDown;
MouseUp += ControlBase_MouseUp;
//MouseMove += ControlBase_MouseMove;
}
//=====公共方法=====
public Bitmap ToImage()
{
IntPtr hSrce = API.GetWindowDC(Handle);
IntPtr hDest = API.CreateCompatibleDC(hSrce);
IntPtr hBmp = API.CreateCompatibleBitmap(hSrce, Width, Height);
IntPtr hOldBmp = API.SelectObject(hDest, hBmp);
if (API.BitBlt(hDest, 0, 0, Width, Height, hSrce, 0, 0, CopyPixelOperation.SourceCopy | CopyPixelOperation.CaptureBlt))
{
Bitmap bmp = Image.FromHbitmap(hBmp);
API.SelectObject(hDest, hOldBmp);
API.DeleteObject(hBmp);
API.DeleteDC(hDest);
API.ReleaseDC(Handle, hSrce);
return bmp;
}
return null;
}
//=====子类方法=====
protected virtual void CalcSize()
{
//边框位置
float x = _borderWidth / 2f;
float y = _borderWidth / 2f;
float width = ClientSize.Width - _borderWidth - 1;
float height = ClientSize.Height - _borderWidth - 1;
borderRect = new RectangleF(x, y, width, height);
//边框路径
borderPath = new GraphicsPath();
dicShape[_faceShape].Invoke();
}
protected virtual void DrawEnabled(Graphics g)
{
//borderEnterChanged = borderEnter;
}
protected virtual void DrawDisabled(Graphics g)
{
}
public virtual void LostFocused()
{
}
//=====属性=====
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int BorderWidth
{
get => _borderWidth;
set
{
_borderWidth = value > 0 ? value : 0;
CalcSize();
Refresh();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new ControlShape BorderStyle
{
get => _faceShape;
set
{
_faceShape = value;
CalcSize();
Refresh();
}
}
[Browsable(false)]
public new Font Font { get => new("宋体", 9f); set => base.Font = new("宋体", 9f); }
private void ShapeRectangle()
{
borderPath.AddRectangle(borderRect);
}
private void ShapeRoundRectangle()
{
float n = borderRect.Height / 8f;
borderPath.AddLine(borderRect.X + n, borderRect.Y, borderRect.Right - n, borderRect.Y);
borderPath.AddArc(borderRect.Right - n - n, borderRect.Y, n + n, n + n, 270, 90);
borderPath.AddLine(borderRect.Right, borderRect.Y + n, borderRect.Right, borderRect.Bottom - n);
borderPath.AddArc(borderRect.Right - n - n, borderRect.Bottom - n - n, n + n, n + n, 0, 90);
borderPath.AddLine(borderRect.Right - n, borderRect.Bottom, borderRect.X + n, borderRect.Bottom);
borderPath.AddArc(borderRect.X, borderRect.Bottom - n - n, n + n, n + n, 90, 90);
borderPath.AddLine(borderRect.X, borderRect.Bottom - n, borderRect.X, borderRect.Y + n);
borderPath.AddArc(borderRect.X, borderRect.Y, n + n, n + n, 180, 90);
}
private void ShapeEllipse()
{
borderPath.AddEllipse(borderRect);
}
private void ShapeEllipseRectangle()
{
float n = borderRect.Height / 2f;
borderPath.AddLine(borderRect.X + n, borderRect.Y, borderRect.Right - n, borderRect.Y);
borderPath.AddArc(borderRect.Right - n - n, borderRect.Y, n + n, n + n, 270, 180);
borderPath.AddLine(borderRect.Right - n, borderRect.Bottom, borderRect.X + n, borderRect.Bottom);
borderPath.AddArc(borderRect.X, borderRect.Y, n + n, n + n, 90, 180);
}
private void ShapeCircle()
{
if (borderRect.Width > borderRect.Height)
borderPath.AddEllipse((borderRect.Width - borderRect.Height) / 2f, borderRect.Y, borderRect.Height, borderRect.Height);
else
borderPath.AddEllipse(borderRect.X, (borderRect.Height - borderRect.Width) / 2f, borderRect.Width, borderRect.Width);
}
private void DrawBorder(Graphics g)
{
//边框以外的部分
Region reg = new(ClientRectangle);
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(BackColor), reg);
//边框
if (_borderWidth > 0)
{
//Color color = theme.DISABLED;
//if (Enabled)
// color = borderEnter ? theme.BORDER_ENTER : theme.BORDER_LEAVE;
Color color = Enabled ? theme.BORDER_ENTER : theme.DISABLED;
Pen pen = new(color, _borderWidth);
g.DrawPath(pen, borderPath);
}
}
private void ControlBase_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void ControlBase_Paint(object sender, PaintEventArgs e)
{
BufferedGraphicsContext current = BufferedGraphicsManager.Current;
BufferedGraphics bg = current.Allocate(e.Graphics, e.ClipRectangle);
Graphics g = bg.Graphics;
g.SmoothingMode = SmoothingMode.HighQuality;
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.Clear(BackColor); //背景
if (Enabled)
DrawEnabled(g);
else
DrawDisabled(g);
DrawBorder(g);
bg.Render();
bg.Dispose();
}
//private void ControlBase_MouseEnter(object sender, EventArgs e)
//{
//}
//private void ControlBase_MouseLeave(object sender, EventArgs e)
//{
// borderEnter = false;
// Refresh();
//}
private void ControlBase_MouseDown(object sender, MouseEventArgs e)
{
if (TopLevelControl is FormBase frm)
frm.SetLostFocus(frm, Handle);
if (e.Button == MouseButtons.Left)
{
mouseLeftDown = true;
mouseRightDown = false;
}
else if (e.Button == MouseButtons.Right)
{
mouseLeftDown = false;
mouseRightDown = true;
}
Refresh();
}
private void ControlBase_MouseUp(object sender, MouseEventArgs e)
{
mouseLeftDown = false;
mouseRightDown = false;
Refresh();
}
//private void ControlBase_MouseMove(object sender, MouseEventArgs e)
//{
// borderEnter = borderPath.IsVisible(e.Location);
// if (borderEnterChanged != borderEnter)
// Refresh();
//}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceButton
{
/// <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()
{
this.SuspendLayout();
//
// FaceButton
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceButton";
this.Size = new System.Drawing.Size(90, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FaceButton : ControlBase
{
private bool _holdPress = false;
private bool _holdDown = false;
private Bitmap _image = null;
private TextImageRelation _textImageRelation = TextImageRelation.Overlay;
private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;
//private bool holdPress = false;
private Bitmap imageDisabled;
private RectangleF textRect;
private RectangleF imageRect;
private readonly Dictionary<TextImageRelation, Action> dicTextImage;
private const int SPACE = 6; //图片与文字的间隔
public FaceButton()
{
InitializeComponent();
dicTextImage = new Dictionary<TextImageRelation, Action>
{
{ TextImageRelation.Overlay, CalcOverlay },
{ TextImageRelation.ImageAboveText, CalcImageAboveText },
{ TextImageRelation.TextAboveImage, CalcTextAboveImage },
{ TextImageRelation.ImageBeforeText, CalcImageBeforeText },
{ TextImageRelation.TextBeforeImage, CalcTextBeforeImage }
};
}
[Browsable(false)]
public bool HoldPress
{
get => _holdPress;
set
{
_holdPress = value;
Refresh();
}
}
[Browsable(true), Category(""), Description(""), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool HoldDown { get => _holdDown; set => _holdDown = value; }
[Browsable(true), Category("外观"), Description("控件上显示的图像"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Bitmap Image
{
get => _image;
set
{
_image = value;
imageDisabled = ImageConvert.ToDisabledGray(value, 80);
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(TextImageRelation.Overlay)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public TextImageRelation TextImageRelation
{
get => _textImageRelation;
set
{
_textImageRelation = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(ContentAlignment.MiddleCenter)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public ContentAlignment TextAlign
{
get => _textAlign;
set
{
_textAlign = value;
CalcSize();
Refresh();
}
}
protected override void CalcSize()
{
base.CalcSize();
using Graphics g = CreateGraphics();
int width = Width - BorderWidth - BorderWidth;
SizeF sf = g.MeasureString(Text, Font, width, stringFormat);
textRect = new(0, 0, sf.Width, sf.Height);
if (_image == null)
{
textRect.Location = CalcTextAlign(sf);
}
else
{
imageRect = new(0, 0, _image.Width, _image.Height);
dicTextImage[TextImageRelation].Invoke();
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (borderEnter)
{
if (_holdDown)
{
if (mouseLeftDown)
{
g.FillPath(new SolidBrush(theme.DOWN), borderPath); //按下
_holdPress = !_holdPress;
}
else if (_holdPress)
{
g.FillPath(new SolidBrush(theme.DOWN), borderPath); //按下
}
else
{
g.FillPath(new SolidBrush(theme.OVER), borderPath); //经过
}
}
else
{
if (mouseLeftDown)
g.FillPath(new SolidBrush(theme.DOWN), borderPath); //按下
else
g.FillPath(new SolidBrush(theme.OVER), borderPath); //经过
}
}
else
{
if (_holdPress)
{
g.FillPath(new SolidBrush(theme.DOWN), borderPath);
}
}
//图标
if (_image != null) g.DrawImage(_image, imageRect);
//文字
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect, stringFormat);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//图标
if (imageDisabled != null) g.DrawImage(imageDisabled, imageRect);
//文字
g.DrawString(Text, Font, new SolidBrush(theme.DISABLED), textRect, stringFormat);
}
/// <summary>
/// 文本对齐位置
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
private PointF CalcTextAlign(SizeF size)
{
PointF pt = new();
switch (_textAlign)
{
case ContentAlignment.TopLeft: pt = new PointF(Padding.Left, Padding.Top); break;
case ContentAlignment.TopCenter: pt = new PointF((Width - size.Width) / 2f, Padding.Top); break;
case ContentAlignment.TopRight: pt = new PointF(Width - size.Width - Padding.Right, Padding.Top); break;
case ContentAlignment.MiddleLeft: pt = new PointF(Padding.Left, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleCenter: pt = new PointF((Width - size.Width) / 2f, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleRight: pt = new PointF(Width - size.Width - Padding.Right, (Height - size.Height) / 2f); break;
case ContentAlignment.BottomLeft: pt = new PointF(Padding.Left, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomCenter: pt = new PointF((Width - size.Width) / 2f, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomRight: pt = new PointF(Width - size.Width - Padding.Right, Height - size.Height - Padding.Bottom); break;
}
return pt;
}
/// <summary>
/// 图像和文本共享控件上的同一空间
/// </summary>
private void CalcOverlay()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
/// <summary>
/// 图像垂直显示在文本的上方
/// </summary>
private void CalcImageAboveText()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = textRect.Height + imageRect.Height + SPACE;
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y + imageRect.Height + SPACE;
}
/// <summary>
/// 文本垂直显示在图像的上方
/// </summary>
private void CalcTextAboveImage()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = textRect.Height + imageRect.Height + SPACE;
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y + textRect.Height + SPACE;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y;
}
/// <summary>
/// 图像水平显示在文本的前方
/// </summary>
private void CalcImageBeforeText()
{
SizeF size = new();
size.Width = textRect.Width + imageRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X + imageRect.Width + SPACE;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
/// <summary>
/// 文本水平显示在图像的前方
/// </summary>
private void CalcTextBeforeImage()
{
SizeF size = new();
size.Width = textRect.Width + imageRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + textRect.Width + SPACE;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceCheckBox
{
/// <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()
{
this.SuspendLayout();
//
// FaceCheckBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceCheckBox";
this.Size = new System.Drawing.Size(130, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("CheckedChanged")]
public partial class FaceCheckBox : ControlBase
{
private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;
private bool _check = false;
private int _checkWidth = 18;
private RectangleF textRect;
private RectangleF checkRect;
private const int SPACE = 6; //图片与文字的间隔
private readonly Pen penBorderEnter;
private readonly Pen penBorderLeave;
private readonly Pen penCheckLine;
public FaceCheckBox()
{
InitializeComponent();
penBorderEnter = new(theme.BORDER_ENTER, 2);
penBorderLeave = new(theme.BORDER_LEAVE, 2);
penCheckLine = new(theme.FORE, 2);
MouseUp += FaceCheckBox_MouseUp;
}
[Browsable(true), Category("杂项"), Description("当checked属性更改值时发生")]
public event EventHandler CheckedChanged;
[Browsable(true), Category("外观"), Description("控件上矩形开关的宽度"), DefaultValue(18)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int CheckWidth
{
get => _checkWidth;
set
{
_checkWidth = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category(""), Description("单选按钮是否已选中"), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool Checked
{
set
{
if (_check != value)
{
_check = value;
CalcSize();
Refresh();
}
CheckedChanged?.Invoke(this, new EventArgs());
}
get
{
return _check;
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(ContentAlignment.MiddleCenter)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public ContentAlignment TextAlign
{
get => _textAlign;
set
{
_textAlign = value;
CalcSize();
Refresh();
}
}
protected override void CalcSize()
{
base.CalcSize();
using Graphics g = CreateGraphics();
checkRect = new(0, 0, _checkWidth + 2, _checkWidth + 2);
int width = Width - BorderWidth - BorderWidth - _checkWidth - 2;
SizeF sf = g.MeasureString(Text, Font, width, stringFormat);
textRect = new(0, 0, sf.Width, sf.Height);
SizeF size = new();
size.Width = textRect.Width + checkRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, checkRect.Height);
PointF pt = CalcTextAlign(size);
checkRect.X = pt.X + 1;
checkRect.Y = pt.Y + (size.Height - checkRect.Height) / 2f;
textRect.X = pt.X + checkRect.Width + SPACE;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (mouseLeftDown)
_check = !_check;
if (_check)
{
g.FillRectangle(new SolidBrush(theme.BORDER_ENTER), checkRect);
float y1 = checkRect.Y + checkRect.Height / 2f;
float x2 = checkRect.X + checkRect.Width / 3f;
float y2 = checkRect.Bottom - 2;
g.DrawLine(penCheckLine, checkRect.X + 2, y1, x2, y2);
g.DrawLine(penCheckLine, x2, y2, checkRect.Right - 2, checkRect.Y + 2);
}
//复选框边框
if (borderEnter)
g.DrawRectangle(penBorderEnter, checkRect.X, checkRect.Y, checkRect.Width, checkRect.Height);
else
g.DrawRectangle(penBorderLeave, checkRect.X, checkRect.Y, checkRect.Width, checkRect.Height);
//文字
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect, stringFormat);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
Pen pen = new(theme.DISABLED, 2);
g.DrawRectangle(pen, checkRect.X, checkRect.Y, checkRect.Width, checkRect.Height);
//文字
g.DrawString(Text, Font, new SolidBrush(theme.DISABLED), textRect, stringFormat);
}
/// <summary>
/// 文本对齐位置
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
private PointF CalcTextAlign(SizeF size)
{
PointF pt = new();
switch (TextAlign)
{
case ContentAlignment.TopLeft: pt = new PointF(Padding.Left, Padding.Top); break;
case ContentAlignment.TopCenter: pt = new PointF((Width - size.Width) / 2f, Padding.Top); break;
case ContentAlignment.TopRight: pt = new PointF(Width - size.Width - Padding.Right, Padding.Top); break;
case ContentAlignment.MiddleLeft: pt = new PointF(Padding.Left, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleCenter: pt = new PointF((Width - size.Width) / 2f, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleRight: pt = new PointF(Width - size.Width - Padding.Right, (Height - size.Height) / 2f); break;
case ContentAlignment.BottomLeft: pt = new PointF(Padding.Left, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomCenter: pt = new PointF((Width - size.Width) / 2f, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomRight: pt = new PointF(Width - size.Width - Padding.Right, Height - size.Height - Padding.Bottom); break;
}
return pt;
}
private void FaceCheckBox_MouseUp(object sender, MouseEventArgs e)
{
CheckedChanged?.Invoke(this, new EventArgs());
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceComboBox
{
/// <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()
{
this.SuspendLayout();
//
// FaceComboBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceComboBox";
this.Size = new System.Drawing.Size(130, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("SelectedIndexChanged")]
public partial class FaceComboBox : ControlBase
{
private CtlComboArrow arrow;
private TextBox ctlText;
private FaceListBox listbox;
public FaceComboBox()
{
InitializeComponent();
arrow = new();
arrow.MouseEnter += Arrow_MouseEnter;
arrow.Click += Arrow_Click;
listbox = new() { Visible = false };
//listbox.LostFocus += Listbox_LostFocus;
listbox.SelectedIndexChanged += Listbox_SelectedIndexChanged;
ctlText = new() { BorderStyle = System.Windows.Forms.BorderStyle.None, BackColor = theme.BACK, ForeColor = theme.FORE };
ctlText.KeyPress += CtlText_KeyPress;
ctlText.MouseEnter += CtlText_MouseEnter;
ctlText.MouseLeave += CtlText_MouseLeave;
ctlText.TextChanged += CtlText_TextChanged;
Controls.Add(arrow);
Controls.Add(ctlText);
}
[Browsable(true), Category("行为"), Description("属性值更改时发生")]
public event EventHandler SelectedIndexChanged;
[Browsable(true), Category("行为"), Description("控制能否更改编辑控件中的文本"), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ReadOnly { set => ctlText.ReadOnly = value; get => ctlText.ReadOnly; }
[Browsable(false)]
public int SelectedIndex { set => listbox.SelectedIndex = value; get => listbox.SelectedIndex; }
[Browsable(false)]
public string SelectedText { set => listbox.Text = value; get => listbox.Text; }
[Browsable(true), Category("外观"), Description("指示应该如何对齐编辑控件的文本"), DefaultValue(HorizontalAlignment.Left)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public HorizontalAlignment TextAlign { set => ctlText.TextAlign = value; get => ctlText.TextAlign; }
[Browsable(true), Category("外观"), Description("用于显示控件中文本的字体")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Font Font
{
get => base.Font;
set
{
base.Font = value;
CalcSize();
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text { get => ctlText.Text; set => ctlText.Text = value; }
[Browsable(false)]
public FaceListBox.Item Items { get => listbox.Items; }
protected override void CalcSize()
{
base.CalcSize();
if (arrow != null)
{
arrow.Top = BorderWidth + 1;
arrow.Height = Height - BorderWidth - BorderWidth - 2;
arrow.Width = 30;
arrow.Left = Width - BorderWidth - arrow.Width - 1;
}
if (ctlText != null)
{
ctlText.Width = arrow.Left - BorderWidth - 5;
ctlText.Left = BorderWidth + 3;
ctlText.Top = (Height - ctlText.Height) / 2 + 1;
}
}
public override void LostFocused()
{
base.LostFocused();
HideDropDown();
arrow.Press = false;
}
private void HideDropDown()
{
Control ctl = listbox.Parent;
if (ctl == null) return;
ctl.Controls.Remove(listbox);
listbox.Visible = false;
}
private void Listbox_SelectedIndexChanged(object sender, EventArgs e)
{
ctlText.Text = listbox.Items[listbox.SelectedIndex];
HideDropDown();
arrow.Press = false;
SelectedIndexChanged?.Invoke(this, new EventArgs());
}
private void Arrow_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void Arrow_Click(object sender, EventArgs e)
{
if (arrow.Press)
{
Control ctl = TopLevelControl;
Point pt = PointToScreen(new Point(0, Height));
listbox.Location = ctl.PointToClient(pt);
listbox.Width = Width;
ctl.Controls.Add(listbox);
listbox.BringToFront();
listbox.Visible = true;
listbox.Focus();
}
else
{
HideDropDown();
}
}
private void CtlText_TextChanged(object sender, EventArgs e)
{
//TextChanged?.Invoke(this, new EventArgs());
}
private void CtlText_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void CtlText_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
listbox.Text = ctlText.Text;
//else if (e.KeyChar == '\n')
//{ }
//else
// KeyPress?.Invoke(this, e);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceLabel
{
/// <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()
{
this.SuspendLayout();
//
// FaceLabel
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceLabel";
this.Size = new System.Drawing.Size(90, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FaceLabel : ControlBase
{
private Bitmap _image = null;
private TextImageRelation _textImageRelation = TextImageRelation.Overlay;
private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;
private Bitmap imageDisabled;
private RectangleF textRect;
private RectangleF imageRect;
private readonly Dictionary<TextImageRelation, Action> dicTextImage;
private const int SPACE = 6; //图片与文字的间隔
public FaceLabel()
{
InitializeComponent();
dicTextImage = new Dictionary<TextImageRelation, Action>
{
{ TextImageRelation.Overlay, CalcOverlay },
{ TextImageRelation.ImageAboveText, CalcImageAboveText },
{ TextImageRelation.TextAboveImage, CalcTextAboveImage },
{ TextImageRelation.ImageBeforeText, CalcImageBeforeText },
{ TextImageRelation.TextBeforeImage, CalcTextBeforeImage }
};
}
[Browsable(true), Category("外观"), Description("控件上显示的图像"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Bitmap Image
{
get => _image;
set
{
_image = value;
imageDisabled = ImageConvert.ToDisabledGray(value);
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(TextImageRelation.Overlay)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public TextImageRelation TextImageRelation
{
get => _textImageRelation;
set
{
_textImageRelation = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(ContentAlignment.MiddleCenter)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public ContentAlignment TextAlign
{
get => _textAlign;
set
{
_textAlign = value;
CalcSize();
Refresh();
}
}
protected override void CalcSize()
{
base.CalcSize();
using Graphics g = CreateGraphics();
int width = Width - BorderWidth - BorderWidth;
SizeF sf = g.MeasureString(Text, Font, width, stringFormat);
textRect = new(0, 0, sf.Width, sf.Height);
if (_image == null)
{
textRect.Location = CalcTextAlign(sf);
}
else
{
imageRect = new(0, 0, _image.Width, _image.Height);
dicTextImage[TextImageRelation].Invoke();
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (_image != null)
g.DrawImage(_image, imageRect);
//文字
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect, stringFormat);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
if (imageDisabled != null)
g.DrawImage(imageDisabled, imageRect);
//文字
g.DrawString(Text, Font, new SolidBrush(theme.DISABLED), textRect, stringFormat);
}
/// <summary>
/// 文本对齐位置
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
private PointF CalcTextAlign(SizeF size)
{
PointF pt = new();
switch (TextAlign)
{
case ContentAlignment.TopLeft: pt = new PointF(Padding.Left, Padding.Top); break;
case ContentAlignment.TopCenter: pt = new PointF((Width - size.Width) / 2f, Padding.Top); break;
case ContentAlignment.TopRight: pt = new PointF(Width - size.Width - Padding.Right, Padding.Top); break;
case ContentAlignment.MiddleLeft: pt = new PointF(Padding.Left, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleCenter: pt = new PointF((Width - size.Width) / 2f, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleRight: pt = new PointF(Width - size.Width - Padding.Right, (Height - size.Height) / 2f); break;
case ContentAlignment.BottomLeft: pt = new PointF(Padding.Left, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomCenter: pt = new PointF((Width - size.Width) / 2f, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomRight: pt = new PointF(Width - size.Width - Padding.Right, Height - size.Height - Padding.Bottom); break;
}
return pt;
}
/// <summary>
/// 图像和文本共享控件上的同一空间
/// </summary>
private void CalcOverlay()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
/// <summary>
/// 图像垂直显示在文本的上方
/// </summary>
private void CalcImageAboveText()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = textRect.Height + imageRect.Height + SPACE;
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y + imageRect.Height + SPACE;
}
/// <summary>
/// 文本垂直显示在图像的上方
/// </summary>
private void CalcTextAboveImage()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = textRect.Height + imageRect.Height + SPACE;
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y + textRect.Height + SPACE;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y;
}
/// <summary>
/// 图像水平显示在文本的前方
/// </summary>
private void CalcImageBeforeText()
{
SizeF size = new();
size.Width = textRect.Width + imageRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X + imageRect.Width + SPACE;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
/// <summary>
/// 文本水平显示在图像的前方
/// </summary>
private void CalcTextBeforeImage()
{
SizeF size = new();
size.Width = textRect.Width + imageRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + textRect.Width + SPACE;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceListBox
{
/// <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()
{
this.SuspendLayout();
//
// FaceListBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceListBox";
this.Size = new System.Drawing.Size(150, 150);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("SelectedIndexChanged")]
public partial class FaceListBox : ControlBase
{
private Item _item;
private int _itemHeight = 30;
private int _selectedIndex = -1;
private HorizontalAlignment _textAlign = HorizontalAlignment.Center;
private FaceScrollBar scrollBar;
private RectangleF[] itemRect;
private RectangleF[] itemTextRect;
private int itemOver = -1;
private float itemOffset = 0;
private float itemStep = 0;
private bool scrollVisible;
private readonly SolidBrush BRUSH_OVER;
private readonly SolidBrush BRUSH_DOWN;
private readonly SolidBrush BRUSH_LINE_1;
private readonly SolidBrush BRUSH_LINE_2;
public FaceListBox()
{
InitializeComponent();
BRUSH_OVER = new SolidBrush(theme.OVER);
BRUSH_DOWN = new SolidBrush(theme.DOWN);
BRUSH_LINE_1 = new SolidBrush(theme.LIST_LINE_1);
BRUSH_LINE_2 = new SolidBrush(theme.LIST_LINE_2);
MouseUp += FaceListBox_MouseUp;
MouseDown += FaceListBox_MouseDown;
MouseMove += FaceListBox_MouseMove;
MouseLeave += FaceListBox_MouseLeave;
MouseWheel += FaceListBox_MouseWheel;
Resize += FaceListBox_Resize;
scrollVisible = false;
scrollBar = new() { Visible = false };
scrollBar.MouseEnter += ScrollBar_MouseEnter;
scrollBar.MouseLeave += ScrollBar_MouseLeave;
scrollBar.Scroll += ScrollBar_Scroll;
Controls.Add(scrollBar);
_item = new Item(ItemRefresh);
}
[Browsable(true), Category("行为"), Description("属性值更改时发生")]
public event EventHandler SelectedIndexChanged;
[Browsable(true), Category("外观"), Description("控件上显示的文本的对齐方式"), DefaultValue(HorizontalAlignment.Center)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public HorizontalAlignment TextAlign
{
get => _textAlign;
set
{
_textAlign = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description(""), DefaultValue(30)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int ItemHeight { set => _itemHeight = value; get => _itemHeight; }
[Browsable(false)]
public int SelectedIndex
{
get => _selectedIndex;
set
{
if (_item.list.Count == 0)
_selectedIndex = -1;
else if (value >= _item.list.Count)
_selectedIndex = _item.list.Count - 1;
else if (value < 0)
_selectedIndex = -1;
else
_selectedIndex = value;
if (scrollVisible && _selectedIndex > -1)
{
float val = (itemRect[_selectedIndex].Top - BorderWidth) / itemStep;
scrollBar.Value += Convert.ToInt32(val);
}
else
{
Refresh();
}
SelectedIndexChanged?.Invoke(this, new EventArgs());
}
}
[Browsable(false)]
public new string Text
{
set
{
int idx = _item.list.FindIndex(match => match == value);
SelectedIndex = idx;
}
get
{
if (_selectedIndex == -1) return "";
return _item[_selectedIndex];
}
}
[Browsable(false)]
public Item Items { get => _item; }
public void SelectedFirst()
{
SelectedIndex = 0;
}
public void SelectedLast()
{
SelectedIndex = _item.list.Count - 1;
}
protected override void CalcSize()
{
base.CalcSize();
if (_item == null) return;
int count = _item.list.Count;
itemRect = new RectangleF[count];
itemTextRect = new RectangleF[count];
float y = BorderWidth - itemOffset;
int width = Width - BorderWidth - BorderWidth - (scrollVisible ? scrollBar.Width : 0);
using Graphics g = CreateGraphics();
for (int i = 0; i < count; i++)
{
itemRect[i] = new RectangleF(BorderWidth, y, width, _itemHeight);
y += _itemHeight;
SizeF sf = g.MeasureString(_item.list[i], Font, itemRect[i].Size, stringFormat);
itemTextRect[i] = new RectangleF(0, itemRect[i].Y + (_itemHeight - sf.Height) / 2f, sf.Width, sf.Height);
switch (TextAlign)
{
case HorizontalAlignment.Left:
itemTextRect[i].X = borderRect.X;
break;
case HorizontalAlignment.Center:
itemTextRect[i].X = borderRect.X + (width - sf.Width) / 2f;
break;
case HorizontalAlignment.Right:
itemTextRect[i].X = borderRect.X + width - sf.Width;
break;
}
}
if (scrollBar != null)
{
scrollBar.Width = 30;
scrollBar.Height = Height - BorderWidth - BorderWidth;
scrollBar.Left = Width - BorderWidth - scrollBar.Width;
scrollBar.Top = BorderWidth;
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
Brush brush;
for (int i = 0; i < itemRect.Length; i++)
{
if (itemRect[i].Bottom < 0) continue;
if (itemRect[i].Y > Height) continue;
if (i == _selectedIndex)
brush = BRUSH_DOWN;
else if (i == itemOver)
brush = BRUSH_OVER;
else
brush = i % 2 == 0 ? BRUSH_LINE_1 : BRUSH_LINE_2;
g.FillRectangle(brush, itemRect[i]);
}
brush = new SolidBrush(ForeColor);
for (int i = 0; i < itemTextRect.Length; i++)
g.DrawString(_item.list[i], Font, brush, itemTextRect[i], stringFormat);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
Brush brush;
for (int i = 0; i < itemRect.Length; i++)
{
if (itemRect[i].Bottom < 0) continue;
if (itemRect[i].Y > Height) continue;
brush = i % 2 == 0 ? BRUSH_LINE_1 : BRUSH_LINE_2;
g.FillRectangle(brush, itemRect[i]);
}
for (int i = 0; i < itemTextRect.Length; i++)
g.DrawString(_item.list[i], Font, BRUSH_DISABLED, itemTextRect[i], stringFormat);
}
private void ItemRefresh()
{
int height = _item.list.Count * _itemHeight + BorderWidth + BorderWidth;
scrollVisible = height > Height;
scrollBar.Visible = scrollVisible;
itemOffset = 0;
if (scrollVisible)
{
float n = height - Height;
scrollBar.Maximum = Convert.ToInt32(Math.Ceiling(n / 10f));
itemStep = n / scrollBar.Maximum;
itemOffset = itemStep * scrollBar.Value;
}
CalcSize();
Refresh();
}
private void FaceListBox_MouseUp(object sender, MouseEventArgs e)
{
SelectedIndexChanged?.Invoke(this, new EventArgs());
}
private void FaceListBox_MouseDown(object sender, MouseEventArgs e)
{
_selectedIndex = itemOver;
}
private void FaceListBox_MouseMove(object sender, MouseEventArgs e)
{
int index = Array.FindIndex(itemRect, match => match.Contains(e.Location));
if (index != itemOver)
{
itemOver = index;
Refresh();
}
}
private void FaceListBox_MouseLeave(object sender, EventArgs e)
{
itemOver = -1;
Refresh();
}
private void FaceListBox_Resize(object sender, EventArgs e)
{
ItemRefresh();
}
private void FaceListBox_MouseWheel(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Delta > 0)
scrollBar.Value--;
else
scrollBar.Value++;
}
private void ScrollBar_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void ScrollBar_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void ScrollBar_Scroll(object sender, ScrollEventArgs e)
{
itemOffset = itemStep * scrollBar.Value;
CalcSize();
Refresh();
}
public class Item
{
internal List<string> list = new();
private Action _action;
public Item(Action action)
{
_action = action;
}
public string this[int index]
{
set
{
if (index >= 0 || index < list.Count)
{
list[index] = value;
_action?.Invoke();
}
}
get
{
if (index < 0 || index >= list.Count)
return "";
else
return list[index];
}
}
public int Count
{
get => list.Count;
}
public void Add(string s)
{
if (s == null) return;
//s = s.Replace('\r', '\0');
//s = s.Replace('\n', '\0');
list.Add(s);
_action?.Invoke();
}
public void AddRange(params string[] s)
{
if (s == null) return;
//for (int i = 0; i < s.Length; i++)
//{
// s[i] = s[i].Replace('\r', '\0');
// s[i] = s[i].Replace('\n', '\0');
//}
list.AddRange(s);
_action?.Invoke();
}
public void Remove(string s)
{
if (s == null) return;
int index = list.FindIndex(match => match == s);
if (index != -1)
{
list.RemoveAt(index);
_action?.Invoke();
}
}
public void Clear()
{
list.Clear();
_action?.Invoke();
}
public void RemoveAt(int index)
{
if (index > -1 && index < list.Count)
{
list.RemoveAt(index);
_action?.Invoke();
}
}
}
public enum ItemChange
{
Add,
AddRange,
RemoveAt,
Clear,
Rename
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceNumericUpDown
{
/// <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()
{
this.SuspendLayout();
//
// FaceNumericUpDown
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceNumericUpDown";
this.Size = new System.Drawing.Size(148, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Value")]
[DefaultEvent("ValueChanged")]
public partial class FaceNumericUpDown : ControlBase
{
private float _min = 0;
private float _max = 100;
private float _value = 0;
private int _decimalPlaces = 2;
private CtlNumericDown numDown;
private CtlNumericUp numUp;
private TextBox ctlText;
public FaceNumericUpDown()
{
InitializeComponent();
numDown = new();
numDown.MouseEnter += NumDown_MouseEnter;
numDown.MouseLeave += NumDown_MouseLeave;
numDown.Click += NumDown_Click;
Controls.Add(numDown);
numUp = new();
numUp.MouseEnter += NumUp_MouseEnter;
numUp.MouseLeave += NumUp_MouseLeave;
numUp.Click += NumUp_Click;
Controls.Add(numUp);
ctlText = new() { BorderStyle = System.Windows.Forms.BorderStyle.None, BackColor = theme.BACK, ForeColor = theme.FORE, ImeMode = ImeMode.Disable };
ctlText.KeyPress += CtlText_KeyPress;
ctlText.MouseEnter += CtlText_MouseEnter;
ctlText.MouseLeave += CtlText_MouseLeave;
ctlText.TextChanged += CtlText_TextChanged;
Controls.Add(ctlText);
Increment = 1;
ShowNumeric();
}
[Browsable(true), Category("操作"), Description("控件中的值更改时发生")]
public event EventHandler ValueChanged;
[Browsable(true), Category("数据"), Description("控件的最小值"), DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public float Minimum
{
get => _min;
set
{
_min = value;
if (_value < _min) _value = _min;
ShowNumeric();
CalcSize();
Refresh();
}
}
[Browsable(true), Category("数据"), Description("控件的最大值"), DefaultValue(100)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public float Maximum
{
get => _max;
set
{
_max = value;
if (_value > _max) _value = _max;
ShowNumeric();
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("控件的当前值"), DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public float Value
{
get => _value;
set
{
if (_value == value) return;
_value = value;
if (_value < _min)
_value = _min;
else if (_value > _max)
_value = _max;
ShowNumeric();
CalcSize();
Refresh();
ValueChanged?.Invoke(this, new EventArgs());
}
}
[Browsable(true), Category("数据"), Description("指示要显示的小数位数"), DefaultValue(2)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int DecimalPlaces
{
get => _decimalPlaces;
set
{
_decimalPlaces = value;
ShowNumeric();
}
}
[Browsable(true), Category("数据"), Description("增加或减少的数量"), DefaultValue(1)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public float Increment { set; get; }
[Browsable(true), Category("行为"), Description("控制能否更改编辑控件中的文本"), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ReadOnly { set => ctlText.ReadOnly = value; get => ctlText.ReadOnly; }
[Browsable(true), Category("外观"), Description("指示应该如何对齐编辑控件的文本"), DefaultValue(HorizontalAlignment.Left)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public HorizontalAlignment TextAlign { set => ctlText.TextAlign = value; get => ctlText.TextAlign; }
[Browsable(true), Category("外观"), Description("用于显示控件中文本的字体")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Font Font
{
get => base.Font;
set
{
base.Font = value;
CalcSize();
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text { get => _value.ToString(); }
protected override void CalcSize()
{
base.CalcSize();
int h = Height - (BorderWidth + 1) * 2;
if (numUp != null)
{
numUp.Width = 30;
numUp.Height = h;
numUp.Left = Width - BorderWidth - numUp.Width - 1;
numUp.Top = BorderWidth + 1;
}
if (numDown != null)
{
numDown.Width = 30;
numDown.Height = h;
numDown.Left = BorderWidth + 1;
numDown.Top = BorderWidth + 1;
}
if (ctlText != null)
{
ctlText.Width = Width - numUp.Width - numDown.Width - (BorderWidth + 3) * 2;
ctlText.Left = numDown.Right + 2;
ctlText.Top = (Height - ctlText.Height) / 2 + 1;
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
}
private void ShowNumeric()
{
ctlText.Text = string.Format("{0:N" + _decimalPlaces + "}", _value);
ctlText.SelectionStart = ctlText.Text.Length;
}
private void NumUp_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void NumUp_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void NumUp_Click(object sender, EventArgs e)
{
Value += Increment;
}
private void NumDown_Click(object sender, EventArgs e)
{
Value -= Increment;
}
private void NumDown_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void NumDown_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void CtlText_TextChanged(object sender, EventArgs e)
{
//TextChanged?.Invoke(this, new EventArgs());
}
private void CtlText_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlText_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == '\r')
{
bool rtn = float.TryParse(ctlText.Text, out float result);
if (rtn) Value = result;
}
//else if (e.KeyChar == '\n')
//{ }
//else
// KeyPress?.Invoke(this, e);
}
private void CtlText_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FacePanel
{
/// <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()
{
this.SuspendLayout();
//
// FacePanel
//
this.Name = "FacePanel";
this.Size = new System.Drawing.Size(187, 181);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FacePanel : PanelBase
{
private Bitmap _image = null;
private TextImageRelation _textImageRelation = TextImageRelation.Overlay;
private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;
private Font _titleFont = new("宋体", 12f);
private int _textHeight = 28;
private bool _showText = true;
private Bitmap imageDisabled;
private RectangleF textRect;
private RectangleF imageRect;
private readonly Dictionary<TextImageRelation, Action> dicTextImage;
private const int SPACE = 6; //图片与文字的间隔
public FacePanel()
{
InitializeComponent();
dicTextImage = new Dictionary<TextImageRelation, Action>
{
{ TextImageRelation.Overlay, CalcOverlay },
{ TextImageRelation.ImageAboveText, CalcImageAboveText },
{ TextImageRelation.TextAboveImage, CalcTextAboveImage },
{ TextImageRelation.ImageBeforeText, CalcImageBeforeText },
{ TextImageRelation.TextBeforeImage, CalcTextBeforeImage }
};
}
//=====事件=====
[Browsable(true)]
public new event EventHandler TextChanged;
[Browsable(true), Category("外观"), Description("控件上显示的图像"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Bitmap Image
{
get => _image;
set
{
_image = value;
imageDisabled = ImageConvert.ToDisabledGray(value);
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(TextImageRelation.Overlay)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public TextImageRelation TextImageRelation
{
get => _textImageRelation;
set
{
_textImageRelation = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(ContentAlignment.MiddleCenter)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public ContentAlignment TextAlign
{
get => _textAlign;
set
{
_textAlign = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本高度"), DefaultValue(28)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int TextHeight
{
get => _textHeight;
set
{
_textHeight = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本是否显示"), DefaultValue(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ShowText
{
get => _showText;
set
{
_showText = value;
CalcSize();
Refresh();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Font TitleFont
{
get => _titleFont;
set
{
_titleFont = value;
CalcSize();
Refresh();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get => base.Text;
set
{
base.Text = value;
CalcSize();
Refresh();
TextChanged?.Invoke(this, new EventArgs());
}
}
protected override void CalcSize()
{
base.CalcSize();
using Graphics g = CreateGraphics();
int width = Width - BorderWidth - BorderWidth;
SizeF sf = g.MeasureString(Text, _titleFont, width, stringFormat);
textRect = new(0, 0, sf.Width, sf.Height);
if (_image == null)
{
textRect.Location = CalcTextAlign(sf);
}
else
{
imageRect = new(0, 0, _image.Width, _image.Height);
dicTextImage[TextImageRelation].Invoke();
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (_showText)
{
g.FillRectangle(new SolidBrush(theme.DOWN), new RectangleF(0, 0, Width, _textHeight + BorderWidth));
if (_image != null)
g.DrawImage(_image, imageRect);
//文字
g.DrawString(Text, _titleFont, new SolidBrush(ForeColor), textRect, stringFormat);
}
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
if (imageDisabled != null)
g.DrawImage(imageDisabled, imageRect);
//文字
g.DrawString(Text, _titleFont, new SolidBrush(theme.DISABLED), textRect, stringFormat);
}
/// <summary>
/// 文本对齐位置
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
private PointF CalcTextAlign(SizeF size)
{
PointF pt = new();
switch (TextAlign)
{
case ContentAlignment.TopLeft: pt = new PointF(Padding.Left, Padding.Top); break;
case ContentAlignment.TopCenter: pt = new PointF((Width - size.Width) / 2f, Padding.Top); break;
case ContentAlignment.TopRight: pt = new PointF(Width - size.Width - Padding.Right, Padding.Top); break;
case ContentAlignment.MiddleLeft: pt = new PointF(Padding.Left, (_textHeight - size.Height) / 2f); break;
case ContentAlignment.MiddleCenter: pt = new PointF((Width - size.Width) / 2f, (_textHeight - size.Height) / 2f); break;
case ContentAlignment.MiddleRight: pt = new PointF(Width - size.Width - Padding.Right, (_textHeight - size.Height) / 2f); break;
case ContentAlignment.BottomLeft: pt = new PointF(Padding.Left, _textHeight - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomCenter: pt = new PointF((Width - size.Width) / 2f, _textHeight - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomRight: pt = new PointF(Width - size.Width - Padding.Right, _textHeight - size.Height - Padding.Bottom); break;
}
return pt;
}
/// <summary>
/// 图像和文本共享控件上的同一空间
/// </summary>
private void CalcOverlay()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
/// <summary>
/// 图像垂直显示在文本的上方
/// </summary>
private void CalcImageAboveText()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = textRect.Height + imageRect.Height + SPACE;
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y + imageRect.Height + SPACE;
}
/// <summary>
/// 文本垂直显示在图像的上方
/// </summary>
private void CalcTextAboveImage()
{
SizeF size = new();
size.Width = Math.Max(textRect.Width, imageRect.Width);
size.Height = textRect.Height + imageRect.Height + SPACE;
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + (size.Width - imageRect.Width) / 2f;
imageRect.Y = pt.Y + textRect.Height + SPACE;
textRect.X = pt.X + (size.Width - textRect.Width) / 2f;
textRect.Y = pt.Y;
}
/// <summary>
/// 图像水平显示在文本的前方
/// </summary>
private void CalcImageBeforeText()
{
SizeF size = new();
size.Width = textRect.Width + imageRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X + imageRect.Width + SPACE;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
/// <summary>
/// 文本水平显示在图像的前方
/// </summary>
private void CalcTextBeforeImage()
{
SizeF size = new();
size.Width = textRect.Width + imageRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, imageRect.Height);
PointF pt = CalcTextAlign(size);
imageRect.X = pt.X + textRect.Width + SPACE;
imageRect.Y = pt.Y + (size.Height - imageRect.Height) / 2f;
textRect.X = pt.X;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FacePasswordLock
{
/// <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()
{
this.SuspendLayout();
//
// FacePasswordLock
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FacePasswordLock";
this.Size = new System.Drawing.Size(240, 240);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("NumberEnter")]
public partial class FacePasswordLock : ControlBase
{
public delegate void NumberEnterHandler(object sender, string text);
public event NumberEnterHandler NumberEnter;
private FaceButton[] button;
private FaceTextBox txtNumber;
private readonly Dictionary<string, string> buttonKeys;
private const int SPACE = 6; //按钮之间的间隔
public FacePasswordLock()
{
InitializeComponent();
buttonKeys = new()
{
{ "1", "1" },
{ "2", "2" },
{ "3", "3" },
{ "4", "4" },
{ "5", "5" },
{ "6", "6" },
{ "7", "7" },
{ "8", "8" },
{ "9", "9" },
{ "0", "0" },
{ "←", "{BACKSPACE}" },
{ "Enter", "{ENTER}" }
};
button = new FaceButton[12];
for (int i = 0; i < button.Length; i++)
{
button[i] = new() { Text = buttonKeys.ElementAt(i).Key };
button[i].MouseEnter += FacePasswordLock_MouseEnter;
button[i].MouseLeave += FacePasswordLock_MouseLeave;
button[i].Click += NumberButton_Click;
}
Controls.AddRange(button);
txtNumber = new() { Text = "", ShowQuery = false, Location = new Point(BorderWidth + SPACE, BorderWidth + SPACE), Height = 45, ImeMode = ImeMode.Disable, TabIndex = 0 };
txtNumber.KeyPress += TxtNumber_KeyPress;
txtNumber.KeyEnterPress += TxtNumber_KeyEnterPress;
Controls.Add(txtNumber);
txtNumber.Focus();
}
[Browsable(true)]
public override string Text { get => txtNumber.Text; set => txtNumber.Text = value; }
public void Clear()
{
txtNumber.Text = "";
}
private void TxtNumber_KeyPress(object sender, KeyPressEventArgs e)
{
if (e.KeyChar == 13) return;
if (e.KeyChar == 8) return;
if (e.KeyChar >= 48 && e.KeyChar <= 57) return;
e.Handled = true;
}
private void TxtNumber_KeyEnterPress(object sender, EventArgs e)
{
NumberEnter?.Invoke(this, txtNumber.Text);
}
private void NumberButton_Click(object sender, EventArgs e)
{
string key = (sender as FaceButton).Text;
txtNumber.Focus();
SendKeys.Send(buttonKeys[key]);
}
private void FacePasswordLock_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void FacePasswordLock_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
protected override void CalcSize()
{
base.CalcSize();
if (button == null) return;
if (txtNumber == null) return;
txtNumber.Width = Width - (BorderWidth + SPACE) * 2;
int startPoint = BorderWidth + SPACE;
int x = startPoint, y = startPoint + txtNumber.Height + SPACE;
int width = (Width - BorderWidth * 2 - SPACE * 4) / 3;
int height = (Height - txtNumber.Height - BorderWidth * 2 - SPACE * 6) / 4;
for (int i = 0; i < button.Length; i++)
{
button[i].Left = x;
button[i].Top = y;
button[i].Width = width;
button[i].Height = height;
x += width + SPACE;
if ((i + 1) % 3 == 0)
{
x = startPoint;
y += height + SPACE;
}
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
//Pen pen = new(theme.BORDER_LEAVE);
//SolidBrush brush = new(ForeColor);
//g.DrawRectangles(pen, buttonRect);
//for (int i = 0; i < buttonTextRect.Length; i++)
// g.DrawString(BUTTON_TEXT[i], Font, brush, buttonTextRect[i]);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//Pen pen = new(theme.DISABLED);
//SolidBrush brush = new(theme.DISABLED);
//g.DrawRectangles(pen, buttonRect);
//for (int i = 0; i < buttonTextRect.Length; i++)
// g.DrawString(BUTTON_TEXT[i], Font, brush, buttonTextRect[i]);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FacePictureBox
{
/// <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()
{
this.SuspendLayout();
//
// FacePictureBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FacePictureBox";
this.Size = new System.Drawing.Size(129, 124);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FacePictureBox : ControlBase
{
private Bitmap _bmp;
private int buttonOver = -1;
private int buttonDown = -1;
private RectangleF[] buttonRect = new RectangleF[3];
private RectangleF[] textRect = new RectangleF[3];
private Point oldPoint = new(0, 0);
private PointF oldOffset = new(0, 0);
private PointF Offset = new(0, 0);
private int oldZoom = 0;
private int zoom = 30; //缩放比例
private List<PointF> codeCenter = new List<PointF>();
private RectangleF[] codeCenterRect;
private const int BUTTON_SIZE = 50;
private readonly string[] BUTTON_TEXT = new string[3] { "-", "+", "□" };
private readonly Font BUTTON_FONT = new("宋体", 20f);
private readonly Font CENTER_FONT = new("宋体", 11f);
private const int ZOOM_MAX = 200; //200%
private const int ZOOM_MIN = 10; //10%
private const int ZOOM_PRECISE = 5; //5%
public FacePictureBox()
{
InitializeComponent();
MouseWheel += FacePictureBox_MouseWheel;
MouseMove += FacePictureBox_MouseMove;
MouseDown += FacePictureBox_MouseDown;
MouseUp += FacePictureBox_MouseUp;
}
[Browsable(true), Category(""), Description("控件上显示的图像"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Bitmap Image
{
get => _bmp;
set
{
_bmp = value;
codeCenter.Clear();
Autofit();
Refresh();
}
}
public void ImagePath(string path)
{
if (System.IO.File.Exists(path))
{
Image = new Bitmap(path);
}
}
public void AddCodeCenter(params PointF[] pt)
{
codeCenter.AddRange(pt);
CalcSize();
Refresh();
}
public void CodeCenterClear()
{
codeCenter.Clear();
CalcSize();
Refresh();
}
protected override void CalcSize()
{
base.CalcSize();
SizeF sf;
Graphics g = CreateGraphics();
float x = borderRect.Right - BUTTON_SIZE * 3;
float y = borderRect.Y + borderRect.Height - BUTTON_SIZE;
for (int i = 0; i < buttonRect.Length; i++)
{
buttonRect[i] = new RectangleF(x, y, BUTTON_SIZE, BUTTON_SIZE);
x += BUTTON_SIZE;
sf = g.MeasureString(BUTTON_TEXT[i], BUTTON_FONT);
textRect[i] = new RectangleF(buttonRect[i].X + (buttonRect[i].Width - sf.Width) / 2f, buttonRect[i].Y + (buttonRect[i].Height - sf.Height) / 2f, sf.Width, sf.Height);
}
codeCenterRect = new RectangleF[codeCenter.Count];
for (int i = 0; i < codeCenterRect.Length; i++)
{
sf = g.MeasureString((i + 1).ToString(), CENTER_FONT);
x = Offset.X + codeCenter[i].X * zoom / 100f - sf.Width / 2f - 3;
y = Offset.Y + codeCenter[i].Y * zoom / 100f - sf.Height / 2f - 3;
codeCenterRect[i] = new RectangleF(x, y, sf.Width, sf.Height);
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (_bmp != null)
{
RectangleF destRect = new RectangleF(Offset.X, Offset.Y, _bmp.Width * zoom / 100f, _bmp.Height * zoom / 100f);
RectangleF srcRect = new RectangleF(0, 0, _bmp.Width, _bmp.Height);
g.DrawImage(_bmp, destRect, srcRect, GraphicsUnit.Pixel);
//Region reg = new Region(new Rectangle(0, 0, Width, Height));
//reg.Exclude(borderPath);
//g.FillRegion(new SolidBrush(theme.BACK), reg);
}
//显示比例
string s = string.Format("{0:F0}%", zoom);
SizeF sf = g.MeasureString(s, BUTTON_FONT);
float w = sf.Width + 10;
g.FillRectangle(new SolidBrush(theme.OVER), borderRect.X, borderRect.Bottom - BUTTON_SIZE, w, BUTTON_SIZE);
g.DrawString(s, BUTTON_FONT, new SolidBrush(ForeColor), borderRect.X + (w - sf.Width) / 2f, borderRect.Bottom - BUTTON_SIZE + (BUTTON_SIZE - sf.Height) / 2f);
for (int i = 0; i < codeCenterRect.Length; i++)
{
g.FillRectangle(Brushes.LightGray, codeCenterRect[i]);
g.DrawString((i + 1).ToString(), CENTER_FONT, Brushes.Red, codeCenterRect[i]);
}
for (int i = 0; i < buttonRect.Length; i++)
{
if (i == buttonDown)
{
g.FillRectangle(new SolidBrush(theme.DOWN), buttonRect[i]);
}
else if (i == buttonOver)
{
g.FillRectangle(new SolidBrush(theme.OVER), buttonRect[i]);
}
}
for (int i = 0; i < textRect.Length; i++)
{
g.DrawString(BUTTON_TEXT[i], BUTTON_FONT, new SolidBrush(ForeColor), textRect[i]);
}
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
}
private void FacePictureBox_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
if (buttonDown == 0)
Small();
else if (buttonDown == 1)
Large();
else if (buttonDown == 2)
Autofit();
buttonDown = -1;
//CalcTextLocation();
Refresh();
}
}
private void FacePictureBox_MouseDown(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
buttonDown = buttonOver;
oldPoint = e.Location;
oldOffset = Offset;
Refresh();
}
}
private void FacePictureBox_MouseMove(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
Offset = new PointF(e.X - oldPoint.X + oldOffset.X, e.Y - oldPoint.Y + oldOffset.Y);
}
else
{
buttonOver = -1;
for (int i = 0; i < buttonRect.Length; i++)
{
if (buttonRect[i].Contains(e.Location))
{
buttonOver = i;
break;
}
}
}
CalcSize();
Refresh();
}
private void FacePictureBox_MouseWheel(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (_bmp == null) return;
oldZoom = zoom;
if (e.Delta > 0)
{
if (zoom < ZOOM_MAX)
zoom += 1;
else
zoom = ZOOM_MAX;
}
else
{
if (zoom > ZOOM_MIN)
zoom -= 1;
else
zoom = ZOOM_MIN;
}
float x = (e.X - Offset.X) * (Width * zoom / 100f) / (Width * oldZoom / 100f);
float y = (e.Y - Offset.Y) * (Height * zoom / 100f) / (Height * oldZoom / 100f);
Offset = new PointF(e.X - x, e.Y - y);
CalcSize();
Refresh();
}
private void Autofit()
{
if (_bmp == null) return;
float w, h;
w = Width;
h = w * _bmp.Height / _bmp.Width;
if (h > Height)
{
h = Height;
w = h * _bmp.Width / _bmp.Height;
}
float scale = w / _bmp.Width * 100f;
if (scale > ZOOM_MAX)
zoom = ZOOM_MAX;
else if (scale < ZOOM_MIN)
zoom = ZOOM_MIN;
else
zoom = Convert.ToInt32(scale);
float x = (Width - _bmp.Width * zoom / 100f) / 2f;
float y = (Height - _bmp.Height * zoom / 100f) / 2f;
Offset = new PointF(x, y);
//Refresh();
}
private void Large()
{
if (_bmp == null) return;
oldZoom = zoom;
if (zoom < ZOOM_MAX)
zoom += ZOOM_PRECISE;
else
zoom = ZOOM_MAX;
float x = (_bmp.Width * zoom / 100f - _bmp.Width * oldZoom / 100f) / 2f;
float y = (_bmp.Height * zoom / 100f - _bmp.Height * oldZoom / 100f) / 2f;
Offset = new PointF(Offset.X - x, Offset.Y - y);
//Refresh();
}
private void Small()
{
if (_bmp == null) return;
oldZoom = zoom;
if (zoom > ZOOM_MIN)
zoom -= ZOOM_PRECISE;
else
zoom = ZOOM_MIN;
float x = (_bmp.Width * zoom / 100f - _bmp.Width * oldZoom / 100f) / 2f;
float y = (_bmp.Height * zoom / 100f - _bmp.Height * oldZoom / 100f) / 2f;
Offset = new PointF(Offset.X - x, Offset.Y - y);
//Refresh();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceRadioBox
{
/// <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()
{
this.SuspendLayout();
//
// FaceRadioBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceRadioBox";
this.Size = new System.Drawing.Size(130, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("CheckedChanged")]
public partial class FaceRadioBox : ControlBase
{
private ContentAlignment _textAlign = ContentAlignment.MiddleCenter;
private bool _check = false;
private int _checkWidth = 18;
private RectangleF textRect;
private RectangleF checkRect;
private const int SPACE = 6; //图片与文字的间隔
private readonly Pen penBorderEnter;
private readonly Pen penBorderLeave;
//private readonly SolidBrush penCheckLine;
public FaceRadioBox()
{
InitializeComponent();
penBorderEnter = new(theme.BORDER_ENTER, 2);
penBorderLeave = new(theme.BORDER_LEAVE, 2);
//penCheckLine = new SolidBrush(theme.FORE);
MouseUp += FaceCheckBox_MouseUp;
MouseDown += FaceRadioBox_MouseDown;
}
[Browsable(true), Category("杂项"), Description("当checked属性更改值时发生")]
public event EventHandler CheckedChanged;
[Browsable(true), Category("外观"), Description("控件上矩形开关的宽度"), DefaultValue(18)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int CheckWidth
{
get => _checkWidth;
set
{
_checkWidth = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category(""), Description("单选按钮是否已选中"), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool Checked
{
set
{
if (_check != value)
{
_check = value;
CalcSize();
Refresh();
}
if (_check) SetGroup();
CheckedChanged?.Invoke(this, new EventArgs());
}
get
{
return _check;
}
}
[Browsable(true), Category(""), Description("相同的内容为一组,同一组的单选按钮只能选中一个。"), DefaultValue("")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string Group { set; get; }
[Browsable(true), Category("外观"), Description("按钮上图像与文本的相对位置"), DefaultValue(ContentAlignment.MiddleCenter)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public ContentAlignment TextAlign
{
get => _textAlign;
set
{
_textAlign = value;
CalcSize();
Refresh();
}
}
protected override void CalcSize()
{
base.CalcSize();
using Graphics g = CreateGraphics();
checkRect = new(0, 0, _checkWidth + 2, _checkWidth + 2);
int width = Width - BorderWidth - BorderWidth - _checkWidth - 2;
SizeF sf = g.MeasureString(Text, Font, width, stringFormat);
textRect = new(0, 0, sf.Width, sf.Height);
SizeF size = new();
size.Width = textRect.Width + checkRect.Width + SPACE;
size.Height = Math.Max(textRect.Height, checkRect.Height);
PointF pt = CalcTextAlign(size);
checkRect.X = pt.X + 1;
checkRect.Y = pt.Y + (size.Height - checkRect.Height) / 2f;
textRect.X = pt.X + checkRect.Width + SPACE;
textRect.Y = pt.Y + (size.Height - textRect.Height) / 2f;
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (mouseLeftDown)
_check = !_check;
if (_check)
{
g.FillEllipse(new SolidBrush(theme.BORDER_ENTER), checkRect);
//float part = _checkWidth / 10f;
//float w = part * 4;
//float h = part * 4;
//float x = checkRect.X + (checkRect.Width - w) / 2f;
//float y = checkRect.Y + (checkRect.Height - h) / 2f;
//g.FillEllipse(penCheckLine, x, y, w, h);
}
//单选框边框
if (borderEnter)
g.DrawEllipse(penBorderEnter, checkRect.X, checkRect.Y, checkRect.Width, checkRect.Height);
else
g.DrawEllipse(penBorderLeave, checkRect.X, checkRect.Y, checkRect.Width, checkRect.Height);
//文字
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect, stringFormat);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
Pen pen = new(theme.DISABLED, 2);
g.DrawEllipse(pen, checkRect.X, checkRect.Y, checkRect.Width, checkRect.Height);
//文字
g.DrawString(Text, Font, new SolidBrush(theme.DISABLED), textRect, stringFormat);
}
/// <summary>
/// 文本对齐位置
/// </summary>
/// <param name="size"></param>
/// <returns></returns>
private PointF CalcTextAlign(SizeF size)
{
PointF pt = new();
switch (TextAlign)
{
case ContentAlignment.TopLeft: pt = new PointF(Padding.Left, Padding.Top); break;
case ContentAlignment.TopCenter: pt = new PointF((Width - size.Width) / 2f, Padding.Top); break;
case ContentAlignment.TopRight: pt = new PointF(Width - size.Width - Padding.Right, Padding.Top); break;
case ContentAlignment.MiddleLeft: pt = new PointF(Padding.Left, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleCenter: pt = new PointF((Width - size.Width) / 2f, (Height - size.Height) / 2f); break;
case ContentAlignment.MiddleRight: pt = new PointF(Width - size.Width - Padding.Right, (Height - size.Height) / 2f); break;
case ContentAlignment.BottomLeft: pt = new PointF(Padding.Left, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomCenter: pt = new PointF((Width - size.Width) / 2f, Height - size.Height - Padding.Bottom); break;
case ContentAlignment.BottomRight: pt = new PointF(Width - size.Width - Padding.Right, Height - size.Height - Padding.Bottom); break;
}
return pt;
}
private void SetGroup()
{
if (Parent == null) return;
foreach (Control ctl in Parent.Controls)
{
if (ctl is FaceRadioBox rdo)
{
if (rdo == this) continue;
if (rdo.Group == Group)
{
if (rdo.Checked)
{
rdo.Checked = false;
break;
}
}
}
}
}
private void FaceRadioBox_MouseDown(object sender, MouseEventArgs e)
{
if (_check) SetGroup();
}
private void FaceCheckBox_MouseUp(object sender, MouseEventArgs e)
{
CheckedChanged?.Invoke(this, new EventArgs());
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceScrollBar
{
/// <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()
{
this.SuspendLayout();
//
// FaceScrollBar
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceScrollBar";
this.Size = new System.Drawing.Size(28, 160);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Value")]
[DefaultEvent("Scroll")]
public partial class FaceScrollBar : ControlBase
{
private int _max = 100;
private int _min = 0;
private int _value = 0;
private CtlScrollUp ctlUp;
private CtlScrollDown ctlDown;
private CtlBar ctlBar;
public FaceScrollBar()
{
InitializeComponent();
ctlUp = new();
ctlUp.Click += CtlUp_Click;
ctlUp.MouseEnter += CtlUp_MouseEnter;
ctlDown = new();
ctlDown.Click += CtlDown_Click;
ctlDown.MouseEnter += CtlDown_MouseEnter;
ctlBar = new();
ctlBar.Click += CtlBar_Click;
ctlBar.MouseEnter += CtlBar_MouseEnter;
ctlBar.ValueChanged += CtlBar_ValueChanged;
ctlBar.SetValue(_min, _max, _value);
Controls.Add(ctlUp);
Controls.Add(ctlDown);
Controls.Add(ctlBar);
}
[Browsable(true), Category("操作"), Description("用户移动滚动框时发生")]
public new event ScrollEventHandler Scroll;
[Browsable(true), Category("行为"), Description("滑块位置的最小值"), DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Minimum
{
get => _min;
set
{
_min = value;
if (ctlBar != null)
{
ctlBar.SetValue(_min, _max, _value);
_value = ctlBar.Value;
}
}
}
[Browsable(true), Category("行为"), Description("滑块位置的最大值"), DefaultValue(100)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Maximum
{
get => _max;
set
{
_max = value;
if (ctlBar != null)
{
ctlBar.SetValue(_min, _max, _value);
_value = ctlBar.Value;
}
}
}
[Browsable(true), Category("行为"), Description("滑块的位置"), DefaultValue(0)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int Value
{
get => _value;
set
{
if (_value == value) return;
int old = _value;
if (ctlBar != null)
{
ctlBar.Value = value;
_value = ctlBar.Value;
}
ScrollEventArgs args = new(ScrollEventType.EndScroll, old, _value);
Scroll?.Invoke(this, args);
}
}
protected override void CalcSize()
{
base.CalcSize();
int left = BorderWidth + 1;
int h = 30;
int w = Width - BorderWidth - BorderWidth - 2;
if (ctlUp != null)
{
ctlUp.Left = left;
ctlUp.Top = BorderWidth + 1;
ctlUp.Width = w;
ctlUp.Height = h;
}
if (ctlDown != null)
{
ctlDown.Left = left;
ctlDown.Top = Height - BorderWidth - h - 1;
ctlDown.Width = w;
ctlDown.Height = h;
}
if (ctlBar != null)
{
ctlBar.Left = left;
ctlBar.Top = BorderWidth + h + 1;
ctlBar.Width = w;
ctlBar.Height = Height - (BorderWidth + h + 1) * 2;
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
}
private void CtlDown_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlDown_Click(object sender, EventArgs e)
{
Value++;
}
private void CtlUp_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlUp_Click(object sender, EventArgs e)
{
Value--;
}
private void CtlBar_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlBar_ValueChanged(object sender, EventArgs e)
{
Value = ctlBar.Value;
}
private void CtlBar_Click(object sender, EventArgs e)
{
//throw new NotImplementedException();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceTextBox
{
/// <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()
{
this.SuspendLayout();
//
// FaceTextBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "FaceTextBox";
this.Size = new System.Drawing.Size(148, 45);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FaceTextBox : ControlBase
{
private bool _showQuery = true;
private bool _showDel = true;
private CtlQuery ctlQuery;
private CtlDel ctlDel;
private TextBox ctlText;
public FaceTextBox()
{
InitializeComponent();
ctlQuery = new() { Visible = false, TabStop = false, TabIndex = 1 };
ctlQuery.Click += CtlQuery_Click;
ctlQuery.MouseEnter += CtlQuery_MouseEnter;
ctlQuery.MouseLeave += CtlQuery_MouseLeave;
ctlDel = new() { Visible = false, TabStop = false, TabIndex = 2 };
ctlDel.Click += CtlDel_Click;
ctlDel.MouseEnter += CtlDel_MouseEnter;
ctlDel.MouseLeave += CtlDel_MouseLeave;
ctlText = new() { BorderStyle = System.Windows.Forms.BorderStyle.None, BackColor = theme.BACK, ForeColor = theme.FORE, TabIndex = 0 };
ctlText.KeyPress += CtlText_KeyPress;
ctlText.KeyDown += CtlText_KeyDown;
ctlText.KeyUp += CtlText_KeyUp;
ctlText.MouseEnter += CtlText_MouseEnter;
ctlText.MouseLeave += CtlText_MouseLeave;
ctlText.TextChanged += CtlText_TextChanged;
Controls.Add(ctlText);
Controls.Add(ctlQuery);
Controls.Add(ctlDel);
GotFocus += FaceTextBox_GotFocus;
}
[Browsable(true), Category("属性已更改"), Description("在控件上更改Text属性的值时引发的事件")]
public new event EventHandler TextChanged;
[Browsable(true), Category("键"), Description("用户按下并释放某个键后发生")]
public new event KeyPressEventHandler KeyPress;
[Browsable(true), Category("键"), Description("用户按下并释放Enter键后发生")]
public event EventHandler KeyEnterPress;
//[Browsable(true), Category("键"), Description("用户按下某个键后发生")]
//public event EventHandler KeyDown;
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ShowQuery
{
get => _showQuery;
set
{
_showQuery = value;
CalcSize();
Refresh();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ShowDel
{
get => _showDel;
set
{
_showDel = value;
CalcSize();
Refresh();
}
}
[Browsable(false), Category(""), Description("选中的文本起始位置")]
public int SelectionStart { set => ctlText.SelectionStart = value; get => ctlText.SelectionStart; }
[Browsable(false), Category(""), Description("选中的文本长度")]
public int SelectionLength { set => ctlText.SelectionLength = value; get => ctlText.SelectionLength; }
[Browsable(false), Category(""), Description("选中的文本")]
public string SelectedText { set => ctlText.SelectedText = value; get => ctlText.SelectedText; }
[Browsable(true), Category("行为"), Description("控件中输入的最大字符数")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int MaxLength { set => ctlText.MaxLength = value; get => ctlText.MaxLength; }
[Browsable(true), Category("行为"), Description("控制能否更改编辑控件中的文本"), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool ReadOnly { set => ctlText.ReadOnly = value; get => ctlText.ReadOnly; }
[Browsable(true), Category("外观"), Description("指示应该如何对齐编辑控件的文本"), DefaultValue(HorizontalAlignment.Left)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public HorizontalAlignment TextAlign { set => ctlText.TextAlign = value; get => ctlText.TextAlign; }
[Browsable(true), Category("外观"), Description("用于显示控件中文本的字体")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Font Font
{
get => base.Font;
set
{
base.Font = value;
CalcSize();
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text { get => ctlText.Text; set => ctlText.Text = value; }
[Browsable(true), DefaultValue(false)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool Multiline
{
get => ctlText.Multiline;
set
{
ctlText.Multiline = value;
CalcSize();
}
}
[Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Color ForeColor
{
get => ctlText.ForeColor;
set
{
if (ctlText != null)
ctlText.ForeColor = value;
}
}
public void AppendText(string s)
{
ctlText.AppendText(s);
}
protected override void CalcSize()
{
base.CalcSize();
int w = BorderWidth + 1;
if (ctlDel != null)
{
if (_showDel)
{
ctlDel.Width = 30;
ctlDel.Height = (int)borderRect.Height - 3;
ctlDel.Left = Width - ctlDel.Width - w;
ctlDel.Top = BorderWidth + 1;
w += ctlDel.Width;
}
ctlDel.Visible = _showDel;
}
if (ctlQuery != null)
{
if (_showQuery)
{
ctlQuery.Width = 30;
ctlQuery.Height = (int)borderRect.Height - 3;
ctlQuery.Left = Width - ctlQuery.Width - w;
ctlQuery.Top = BorderWidth + 1;
w += ctlQuery.Width;
}
ctlQuery.Visible = _showQuery;
}
if (ctlText != null)
{
ctlText.Width = Width - BorderWidth - w - 5;
ctlText.Left = BorderWidth + 3;
if (Multiline)
ctlText.Height = Height - (BorderWidth + 2) * 2;
ctlText.Top = (Height - ctlText.Height) / 2 + 1;
}
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
}
private void FaceTextBox_GotFocus(object sender, EventArgs e)
{
ctlText.Focus();
}
private void CtlDel_Click(object sender, EventArgs e)
{
ctlText.Text = "";
}
private void CtlDel_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlDel_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void CtlQuery_Click(object sender, EventArgs e)
{
KeyEnterPress?.Invoke(this, e);
}
private void CtlQuery_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlQuery_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
private void CtlText_TextChanged(object sender, EventArgs e)
{
TextChanged?.Invoke(this, new EventArgs());
}
private void CtlText_MouseEnter(object sender, EventArgs e)
{
borderEnter = true;
Refresh();
}
private void CtlText_KeyPress(object sender, KeyPressEventArgs e)
{
OnKeyPress(e);
if (e.KeyChar == '\r')
KeyEnterPress?.Invoke(this, e);
else if (e.KeyChar == '\n')
{ }
else
KeyPress?.Invoke(this, e);
}
private void CtlText_KeyDown(object sender, KeyEventArgs e)
{
OnKeyDown(e);
}
private void CtlText_KeyUp(object sender, KeyEventArgs e)
{
OnKeyUp(e);
}
private void CtlText_MouseLeave(object sender, EventArgs e)
{
borderEnter = false;
Refresh();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlBar
{
/// <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()
{
this.SuspendLayout();
//
// CtlBar
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlBar";
this.Size = new System.Drawing.Size(50, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Value")]
[DefaultEvent("ValueChanged")]
public partial class CtlBar : UserControl
{
private int min = 0;
private int max = 100;
private int value = 0;
private RectangleF barRect;
private float step = 0;
private PointF oldPoint;
private bool barDown;
private readonly IFaceThemeColor theme;
private const int MIN_HEIGHT = 15;
private const int MIN_STEP = 5;
private Color backColor;
private SolidBrush barBrush;
public CtlBar()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
barBrush = new SolidBrush(theme.SCROLL_BAR_BACK);
MouseUp += CtlDown_MouseUp;
MouseDown += CtlDown_MouseDown;
MouseMove += CtlBar_MouseMove;
MouseLeave += CtlDown_MouseLeave;
MouseEnter += CtlDown_MouseEnter;
Resize += CtlDown_Resize;
Paint += CtlDown_Paint;
CalcSize();
Refresh();
}
[Browsable(true)]
public event EventHandler ValueChanged;
public int Value
{
get => value;
set
{
if (this.value == value) return;
this.value = value;
if (this.value < min)
this.value = min;
else if (this.value > max)
this.value = max;
CalcSize();
Refresh();
ValueChanged?.Invoke(this, new EventArgs());
}
}
public void SetValue(int min, int max, int value)
{
this.min = min;
this.max = max;
Value = value;
}
private void CalcSize()
{
float h = Height - (max - min) * MIN_STEP;
if (h < MIN_HEIGHT)
{
h = MIN_HEIGHT;
step = (Height - h) / (max - min);
}
else
{
step = MIN_STEP;
}
barRect = new RectangleF(0, (value - min) * step, Width, h);
}
private void CtlDown_MouseUp(object sender, MouseEventArgs e)
{
//mouseLeftDown = false;
barBrush = new SolidBrush(theme.SCROLL_BAR_OVER);
Refresh();
}
private void CtlDown_MouseDown(object sender, MouseEventArgs e)
{
oldPoint = e.Location;
barDown = barRect.Contains(e.Location);
barBrush = new SolidBrush(theme.SCROLL_BAR_DOWN);
Refresh();
if (!barDown)
{
float y = (value - min) * step + barRect.Height / 2f;
int n = Convert.ToInt32((e.Y - y) / step);
oldPoint.Y += n * step;
Value += n;
}
}
private void CtlBar_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
if (barDown)
{
int n = Convert.ToInt32((e.Y - oldPoint.Y) / step);
oldPoint.Y += n * step;
Value += n;
}
}
private void CtlDown_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
barBrush = new SolidBrush(theme.SCROLL_BAR_BACK);
Refresh();
}
private void CtlDown_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
barBrush = new SolidBrush(theme.SCROLL_BAR_OVER);
Refresh();
}
private void CtlDown_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlDown_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.FillRectangle(barBrush, barRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlClose
{
/// <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()
{
this.SuspendLayout();
//
// CtlClose
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlClose";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlClose : UserControl
{
private IFaceThemeColor theme;
private RectangleF textRect;
private Color backColor;
private const string TEXT = "r";
private readonly Font TEXT_FONT = new("Webdings", 12f);
public CtlClose()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlClose_MouseUp;
MouseDown += CtlClose_MouseDown;
MouseLeave += CtlClose_MouseLeave;
MouseEnter += CtlClose_MouseEnter;
Resize += CtlClose_Resize;
Paint += CtlClose_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
Graphics g = CreateGraphics();
SizeF size = g.MeasureString(TEXT, TEXT_FONT);
float x = (Width - size.Width) / 2f;
float y = (Height - size.Height) / 2f;
textRect = new RectangleF(x, y, size.Width, size.Height);
}
private void CtlClose_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.TITLE_CLOSE_BUTTON_OVER;
Refresh();
}
private void CtlClose_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.TITLE_CLOSE_BUTTON_DOWN;
Refresh();
}
private void CtlClose_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlClose_MouseEnter(object sender, EventArgs e)
{
backColor = theme.TITLE_CLOSE_BUTTON_OVER;
Refresh();
}
private void CtlClose_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlClose_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
SolidBrush brush = new(theme.TITLE_BUTTON_FORE);
e.Graphics.DrawString(TEXT, TEXT_FONT,brush, textRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlComboArrow
{
/// <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()
{
this.SuspendLayout();
//
// CtlComboArrow
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlComboArrow";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlComboArrow : UserControl
{
private bool _press = false;
private readonly IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new(17, 17);
public CtlComboArrow()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlDown_MouseUp;
MouseDown += CtlDown_MouseDown;
MouseLeave += CtlDown_MouseLeave;
MouseEnter += CtlDown_MouseEnter;
Resize += CtlDown_Resize;
Paint += CtlDown_Paint;
CalcSize();
Refresh();
}
public bool Press
{
get => _press;
set
{
_press = value;
if (_press)
backColor = theme.DOWN;
else
backColor = theme.BACK;
Refresh();
}
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlDown_MouseUp(object sender, MouseEventArgs e)
{
if (!_press)
backColor = theme.OVER;
Refresh();
}
private void CtlDown_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
_press = !_press;
Refresh();
}
private void CtlDown_MouseLeave(object sender, EventArgs e)
{
if (!_press)
backColor = theme.BACK;
Refresh();
}
private void CtlDown_MouseEnter(object sender, EventArgs e)
{
if (!_press)
backColor = theme.OVER;
Refresh();
}
private void CtlDown_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlDown_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
if (_press)
e.Graphics.DrawImage(Resource1.ArrowUp, imageRect);
else
e.Graphics.DrawImage(Resource1.ArrowDown, imageRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlDel
{
/// <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()
{
this.SuspendLayout();
//
// CtlDel
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "CtlDel";
this.Size = new System.Drawing.Size(30, 30);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlDel : UserControl
{
private readonly IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new(17, 17);
public CtlDel()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlDel_MouseUp;
MouseDown += CtlDel_MouseDown;
MouseLeave += CtlDel_MouseLeave;
MouseEnter += CtlDel_MouseEnter;
Resize += CtlDel_Resize;
Paint += CtlDel_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlDel_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlDel_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
Refresh();
}
private void CtlDel_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlDel_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlDel_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlDel_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.DrawImage(Resource1.Delete, imageRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlMax
{
/// <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()
{
this.SuspendLayout();
//
// CtlMax
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlMax";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlMax : UserControl
{
private IFaceThemeColor theme;
private RectangleF textRect;
private Color backColor;
private string text = "1";
private readonly Font TEXT_FONT = new("Webdings", 12f);
public CtlMax()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlMax_MouseUp;
MouseDown += CtlMax_MouseDown;
MouseLeave += CtlMax_MouseLeave;
MouseEnter += CtlMax_MouseEnter;
Resize += CtlMax_Resize;
Paint += CtlMax_Paint;
CalcSize();
Refresh();
}
public void MaxText()
{
text = "2";
CalcSize();
Refresh();
}
public void MinText()
{
text = "1";
CalcSize();
Refresh();
}
private void CalcSize()
{
Graphics g = CreateGraphics();
SizeF size = g.MeasureString(text, TEXT_FONT);
float x = (Width - size.Width) / 2f;
float y = (Height - size.Height) / 2f;
textRect = new RectangleF(x, y, size.Width, size.Height);
}
private void CtlMax_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.TITLE_MAX_BUTTON_OVER;
Refresh();
}
private void CtlMax_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.TITLE_MAX_BUTTON_DOWN;
Refresh();
}
private void CtlMax_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlMax_MouseEnter(object sender, EventArgs e)
{
backColor = theme.TITLE_MAX_BUTTON_OVER;
Refresh();
}
private void CtlMax_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlMax_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
SolidBrush brush = new(theme.TITLE_BUTTON_FORE);
e.Graphics.DrawString(text, TEXT_FONT, brush, textRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlMin
{
/// <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()
{
this.SuspendLayout();
//
// CtlMin
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlMin";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlMin : UserControl
{
private readonly IFaceThemeColor theme;
private RectangleF textRect;
private Color backColor;
private const string TEXT = "0";
private readonly Font TEXT_FONT = new("Webdings", 12f);
public CtlMin()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlMin_MouseUp;
MouseDown += CtlMin_MouseDown;
MouseLeave += CtlMin_MouseLeave;
MouseEnter += CtlMin_MouseEnter;
Resize += CtlMin_Resize;
Paint += CtlMin_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
Graphics g = CreateGraphics();
SizeF size = g.MeasureString(TEXT, TEXT_FONT);
float x = (Width - size.Width) / 2f;
float y = (Height - size.Height) / 2f;
textRect = new RectangleF(x, y, size.Width, size.Height);
}
private void CtlMin_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.TITLE_MIN_BUTTON_OVER;
Refresh();
}
private void CtlMin_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.TITLE_MIN_BUTTON_DOWN;
Refresh();
}
private void CtlMin_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlMin_MouseEnter(object sender, EventArgs e)
{
backColor = theme.TITLE_MIN_BUTTON_OVER;
Refresh();
}
private void CtlMin_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlMin_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
SolidBrush brush = new(theme.TITLE_BUTTON_FORE);
e.Graphics.DrawString(TEXT, TEXT_FONT, brush, textRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlNumericDown
{
/// <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()
{
this.SuspendLayout();
//
// CtlNumericDown
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlNumericDown";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlNumericDown : UserControl
{
private readonly IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new(14, 17);
public CtlNumericDown()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlDown_MouseUp;
MouseDown += CtlDown_MouseDown;
MouseLeave += CtlDown_MouseLeave;
MouseEnter += CtlDown_MouseEnter;
Resize += CtlDown_Resize;
Paint += CtlDown_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlDown_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlDown_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
Refresh();
}
private void CtlDown_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlDown_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlDown_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlDown_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.DrawImage(Resource1.ScrollLeft, imageRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlNumericUp
{
/// <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()
{
this.SuspendLayout();
//
// CtlNumericUp
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlNumericUp";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlNumericUp : UserControl
{
private readonly IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new(14, 17);
public CtlNumericUp()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlUp_MouseUp;
MouseDown += CtlUp_MouseDown;
MouseLeave += CtlUp_MouseLeave;
MouseEnter += CtlUp_MouseEnter;
Resize += CtlUp_Resize;
Paint += CtlUp_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlUp_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlUp_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
Refresh();
}
private void CtlUp_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlUp_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlUp_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlUp_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.DrawImage(Resource1.ScrollRight, imageRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlQuery
{
/// <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()
{
this.SuspendLayout();
//
// CtlQuery
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "CtlQuery";
this.Size = new System.Drawing.Size(30, 30);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlQuery : UserControl
{
private IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new Size(17, 18);
public CtlQuery()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlMin_MouseUp;
MouseDown += CtlMin_MouseDown;
MouseLeave += CtlMin_MouseLeave;
MouseEnter += CtlMin_MouseEnter;
Resize += CtlMin_Resize;
Paint += CtlMin_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlMin_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlMin_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
Refresh();
}
private void CtlMin_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlMin_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlMin_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlMin_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.DrawImage(Resource1.Query, imageRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlScrollDown
{
/// <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()
{
this.SuspendLayout();
//
// CtlDown
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlDown";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlScrollDown : UserControl
{
private readonly IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new(17, 17);
public CtlScrollDown()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlDown_MouseUp;
MouseDown += CtlDown_MouseDown;
MouseLeave += CtlDown_MouseLeave;
MouseEnter += CtlDown_MouseEnter;
Resize += CtlDown_Resize;
Paint += CtlDown_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlDown_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlDown_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
Refresh();
}
private void CtlDown_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlDown_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlDown_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlDown_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.DrawImage(Resource1.ScrollDown, imageRect);
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class CtlScrollUp
{
/// <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()
{
this.SuspendLayout();
//
// CtlUp
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.Name = "CtlUp";
this.Size = new System.Drawing.Size(80, 50);
this.ResumeLayout(false);
}
#endregion
}
}
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 Asa.FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class CtlScrollUp : UserControl
{
private readonly IFaceThemeColor theme;
private RectangleF imageRect;
private Color backColor;
private readonly Size imageSize = new(17, 17);
public CtlScrollUp()
{
InitializeComponent();
theme = new DarkThemeColor();
backColor = theme.BACK;
MouseUp += CtlUp_MouseUp;
MouseDown += CtlUp_MouseDown;
MouseLeave += CtlUp_MouseLeave;
MouseEnter += CtlUp_MouseEnter;
Resize += CtlUp_Resize;
Paint += CtlUp_Paint;
CalcSize();
Refresh();
}
private void CalcSize()
{
float x = (Width - imageSize.Width) / 2f;
float y = (Height - imageSize.Height) / 2f;
imageRect = new RectangleF(x, y, imageSize.Width, imageSize.Height);
}
private void CtlUp_MouseUp(object sender, MouseEventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlUp_MouseDown(object sender, MouseEventArgs e)
{
backColor = theme.DOWN;
Refresh();
}
private void CtlUp_MouseLeave(object sender, EventArgs e)
{
backColor = theme.BACK;
Refresh();
}
private void CtlUp_MouseEnter(object sender, EventArgs e)
{
backColor = theme.OVER;
Refresh();
}
private void CtlUp_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void CtlUp_Paint(object sender, PaintEventArgs e)
{
e.Graphics.Clear(backColor);
e.Graphics.DrawImage(Resource1.ScrollUp, imageRect);
}
}
}
<?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>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{BB46377E-CC9F-4AC2-9367-87503B59EFE7}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>Asa.FaceControl</RootNamespace>
<AssemblyName>Asa.Face.Control</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<Deterministic>false</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<DocumentationFile>
</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<LangVersion>preview</LangVersion>
</PropertyGroup>
<ItemGroup>
<Reference Include="log4net, Version=2.0.12.0, Culture=neutral, PublicKeyToken=669e0ddf0bb1aa2a, processorArchitecture=MSIL">
<HintPath>..\packages\log4net.2.0.12\lib\net45\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Configuration" />
<Reference Include="System.Core" />
<Reference Include="System.Drawing" />
<Reference Include="System.Web" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Control\FaceLabel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceLabel.Designer.cs">
<DependentUpon>FaceLabel.cs</DependentUpon>
</Compile>
<Compile Include="Base\FormBase.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Base\FormBase.Designer.cs">
<DependentUpon>FormBase.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceTextBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceTextBox.Designer.cs">
<DependentUpon>FaceTextBox.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlDel.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlDel.Designer.cs">
<DependentUpon>CtlDel.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlQuery.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlQuery.Designer.cs">
<DependentUpon>CtlQuery.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceCheckBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceCheckBox.Designer.cs">
<DependentUpon>FaceCheckBox.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceRadioBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceRadioBox.Designer.cs">
<DependentUpon>FaceRadioBox.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlScrollUp.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlScrollUp.Designer.cs">
<DependentUpon>CtlScrollUp.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlScrollDown.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlScrollDown.Designer.cs">
<DependentUpon>CtlScrollDown.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceScrollBar.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceScrollBar.Designer.cs">
<DependentUpon>FaceScrollBar.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlBar.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlBar.Designer.cs">
<DependentUpon>CtlBar.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceListBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceListBox.Designer.cs">
<DependentUpon>FaceListBox.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlComboArrow.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlComboArrow.Designer.cs">
<DependentUpon>CtlComboArrow.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceComboBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceComboBox.Designer.cs">
<DependentUpon>FaceComboBox.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlNumericDown.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlNumericDown.Designer.cs">
<DependentUpon>CtlNumericDown.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlNumericUp.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlNumericUp.Designer.cs">
<DependentUpon>CtlNumericUp.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceNumericUpDown.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceNumericUpDown.Designer.cs">
<DependentUpon>FaceNumericUpDown.cs</DependentUpon>
</Compile>
<Compile Include="Control\FacePanel.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Control\FacePanel.Designer.cs">
<DependentUpon>FacePanel.cs</DependentUpon>
</Compile>
<Compile Include="Control\FacePictureBox.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FacePictureBox.Designer.cs">
<DependentUpon>FacePictureBox.cs</DependentUpon>
</Compile>
<Compile Include="Control\FacePasswordLock.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FacePasswordLock.Designer.cs">
<DependentUpon>FacePasswordLock.cs</DependentUpon>
</Compile>
<Compile Include="Form\FaceFormFixed.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form\FaceFormFixed.Designer.cs">
<DependentUpon>FaceFormFixed.cs</DependentUpon>
</Compile>
<Compile Include="Form\FaceInputBox.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form\FaceInputBox.Designer.cs">
<DependentUpon>FaceInputBox.cs</DependentUpon>
</Compile>
<Compile Include="Form\FaceMessageBox.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form\FaceMessageBox.Designer.cs">
<DependentUpon>FaceMessageBox.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlClose.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlClose.Designer.cs">
<DependentUpon>CtlClose.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlMax.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlMax.Designer.cs">
<DependentUpon>CtlMax.cs</DependentUpon>
</Compile>
<Compile Include="ControlParts\CtlMin.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="ControlParts\CtlMin.Designer.cs">
<DependentUpon>CtlMin.cs</DependentUpon>
</Compile>
<Compile Include="Form\FaceFormNormal.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="Form\FaceFormNormal.Designer.cs">
<DependentUpon>FaceFormNormal.cs</DependentUpon>
</Compile>
<Compile Include="BLL\ImageConvert.cs" />
<Compile Include="Language.cs" />
<Compile Include="Model\IFaceThemeColor.cs" />
<Compile Include="Model\ControlShape.cs" />
<Compile Include="Model\API.cs" />
<Compile Include="Model\DarkThemeColor.cs" />
<Compile Include="Base\ControlBase.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Base\ControlBase.Designer.cs">
<DependentUpon>ControlBase.cs</DependentUpon>
</Compile>
<Compile Include="Control\FaceButton.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="Control\FaceButton.Designer.cs">
<DependentUpon>FaceButton.cs</DependentUpon>
</Compile>
<Compile Include="Base\PanelBase.cs">
<SubType>Component</SubType>
</Compile>
<Compile Include="Base\PanelBase.Designer.cs">
<DependentUpon>PanelBase.cs</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Resource1.Designer.cs">
<AutoGen>True</AutoGen>
<DesignTime>True</DesignTime>
<DependentUpon>Resource1.resx</DependentUpon>
</Compile>
</ItemGroup>
<ItemGroup>
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Base\ControlBase.resx">
<DependentUpon>ControlBase.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Base\FormBase.resx">
<DependentUpon>FormBase.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceLabel.resx">
<DependentUpon>FaceLabel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceButton.resx">
<DependentUpon>FaceButton.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceTextBox.resx">
<DependentUpon>FaceTextBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlDel.resx">
<DependentUpon>CtlDel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlQuery.resx">
<DependentUpon>CtlQuery.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceCheckBox.resx">
<DependentUpon>FaceCheckBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceRadioBox.resx">
<DependentUpon>FaceRadioBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlScrollUp.resx">
<DependentUpon>CtlScrollUp.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlScrollDown.resx">
<DependentUpon>CtlScrollDown.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceScrollBar.resx">
<DependentUpon>FaceScrollBar.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlBar.resx">
<DependentUpon>CtlBar.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceListBox.resx">
<DependentUpon>FaceListBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlComboArrow.resx">
<DependentUpon>CtlComboArrow.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceComboBox.resx">
<DependentUpon>FaceComboBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlNumericDown.resx">
<DependentUpon>CtlNumericDown.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlNumericUp.resx">
<DependentUpon>CtlNumericUp.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FaceNumericUpDown.resx">
<DependentUpon>FaceNumericUpDown.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FacePanel.resx">
<DependentUpon>FacePanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FacePictureBox.resx">
<DependentUpon>FacePictureBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Control\FacePasswordLock.resx">
<DependentUpon>FacePasswordLock.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Form\FaceFormFixed.resx">
<DependentUpon>FaceFormFixed.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Form\FaceInputBox.resx">
<DependentUpon>FaceInputBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Form\FaceMessageBox.resx">
<DependentUpon>FaceMessageBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlClose.resx">
<DependentUpon>CtlClose.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlMax.resx">
<DependentUpon>CtlMax.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="ControlParts\CtlMin.resx">
<DependentUpon>CtlMin.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Form\FaceFormNormal.resx">
<DependentUpon>FaceFormNormal.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Base\PanelBase.resx">
<DependentUpon>PanelBase.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Resource1.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resource1.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<Folder Include="DLL\" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Query.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\Delete.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ScrollUp.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ScrollRight.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ScrollLeft.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ScrollDown.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ArrowUp.png" />
</ItemGroup>
<ItemGroup>
<None Include="Resources\ArrowDown.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<PropertyGroup>
<PostBuildEvent>copy "$(TargetPath)" "C:\Neotel\DLL\$(ProjectName)\$(TargetFileName)"
copy "$(TargetDir)$(TargetName).pdb" "C:\Neotel\DLL\$(ProjectName)\$(TargetName).pdb"</PostBuildEvent>
</PropertyGroup>
</Project>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceFormFixed
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ctlMin = new Asa.FaceControl.CtlMin();
this.ctlClose = new Asa.FaceControl.CtlClose();
this.SuspendLayout();
//
// ctlMin
//
this.ctlMin.Location = new System.Drawing.Point(47, 44);
this.ctlMin.Name = "ctlMin";
this.ctlMin.Size = new System.Drawing.Size(80, 50);
this.ctlMin.TabIndex = 5;
//
// ctlClose
//
this.ctlClose.Location = new System.Drawing.Point(133, 44);
this.ctlClose.Name = "ctlClose";
this.ctlClose.Size = new System.Drawing.Size(80, 50);
this.ctlClose.TabIndex = 3;
//
// FaceFormFixed
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(440, 327);
this.Controls.Add(this.ctlMin);
this.Controls.Add(this.ctlClose);
this.Location = new System.Drawing.Point(0, 0);
this.Name = "FaceFormFixed";
this.Text = "FaceFormFixed";
this.TitleFont = new System.Drawing.Font("宋体", 18F);
this.TitleHeight = 45;
this.ResumeLayout(false);
}
#endregion
private CtlMin ctlMin;
private CtlClose ctlClose;
}
}
\ No newline at end of file
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 Asa.FaceControl
{
public partial class FaceFormFixed : FormBase
{
public FaceFormFixed()
{
InitializeComponent();
CanResize = false;
ctlMin.Click += CtlMin_Click;
ctlClose.Click += CtlClose_Click;
}
protected override void CalcSize()
{
base.CalcSize();
CalcLocation();
}
private void CalcLocation()
{
int n = 1;
if (ctlClose != null)
{
ctlClose.Size = new Size(60, 32);
n += ctlClose.Width;
ctlClose.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
if (ctlMin != null)
{
ctlMin.Size = new Size(46, 32);
n += ctlMin.Width;
ctlMin.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlMin.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
}
private void CtlMin_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
private void CtlClose_Click(object sender, EventArgs e)
{
Close();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceFormNormal
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ctlClose = new Asa.FaceControl.CtlClose();
this.ctlMax = new Asa.FaceControl.CtlMax();
this.ctlMin = new Asa.FaceControl.CtlMin();
this.SuspendLayout();
//
// ctlClose
//
this.ctlClose.Location = new System.Drawing.Point(200, 54);
this.ctlClose.Name = "ctlClose";
this.ctlClose.Size = new System.Drawing.Size(80, 50);
this.ctlClose.TabIndex = 0;
//
// ctlMax
//
this.ctlMax.Location = new System.Drawing.Point(114, 54);
this.ctlMax.Name = "ctlMax";
this.ctlMax.Size = new System.Drawing.Size(80, 50);
this.ctlMax.TabIndex = 1;
//
// ctlMin
//
this.ctlMin.Location = new System.Drawing.Point(28, 54);
this.ctlMin.Name = "ctlMin";
this.ctlMin.Size = new System.Drawing.Size(80, 50);
this.ctlMin.TabIndex = 2;
//
// FaceFormNormal
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(406, 276);
this.Controls.Add(this.ctlMin);
this.Controls.Add(this.ctlMax);
this.Controls.Add(this.ctlClose);
this.Location = new System.Drawing.Point(0, 0);
this.Name = "FaceFormNormal";
this.Text = "FaceFormNormal";
this.TitleFont = new System.Drawing.Font("宋体", 18F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
this.TitleHeight = 45;
this.ResumeLayout(false);
}
#endregion
private CtlClose ctlClose;
private CtlMax ctlMax;
private CtlMin ctlMin;
}
}
\ No newline at end of file
using System;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Asa.FaceControl
{
public partial class FaceFormNormal : FormBase
{
public FaceFormNormal()
{
InitializeComponent();
ctlMin.Click += CtlMin_Click;
ctlMax.Click += CtlMax_Click;
ctlClose.Click += CtlClose_Click;
}
protected override void CalcSize()
{
base.CalcSize();
CalcLocation();
}
private void CalcLocation()
{
int n = 1;
if (ctlClose != null)
{
ctlClose.Size = new Size(60, 32);
n += ctlClose.Width;
ctlClose.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
if (ctlMax != null)
{
ctlMax.Size = new Size(46, 32);
n += ctlMax.Width;
ctlMax.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlMax.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
if (ctlMin != null)
{
ctlMin.Size = new Size(46, 32);
n += ctlMin.Width;
ctlMin.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlMin.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
}
private void CtlMin_Click(object sender, EventArgs e)
{
WindowState = FormWindowState.Minimized;
}
private void CtlMax_Click(object sender, EventArgs e)
{
if (IsMaximized)
{
Restore();
ctlMax.MinText();
}
else
{
Maximize();
ctlMax.MaxText();
}
}
private void CtlClose_Click(object sender, EventArgs e)
{
Close();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceInputBox
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ctlClose = new Asa.FaceControl.CtlClose();
this.BtnOK = new Asa.FaceControl.FaceButton();
this.BtnCancel = new Asa.FaceControl.FaceButton();
this.faceTextBox1 = new Asa.FaceControl.FaceTextBox();
this.faceLabel1 = new Asa.FaceControl.FaceLabel();
this.SuspendLayout();
//
// ctlClose
//
this.ctlClose.Location = new System.Drawing.Point(67, 11);
this.ctlClose.Name = "ctlClose";
this.ctlClose.Size = new System.Drawing.Size(80, 23);
this.ctlClose.TabIndex = 4;
//
// BtnOK
//
this.BtnOK.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.BtnOK.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.BtnOK.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.BtnOK.BorderWidth = 2;
this.BtnOK.Font = new System.Drawing.Font("宋体", 12F);
this.BtnOK.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.BtnOK.Location = new System.Drawing.Point(251, 270);
this.BtnOK.Name = "BtnOK";
this.BtnOK.Padding = new System.Windows.Forms.Padding(3);
this.BtnOK.Size = new System.Drawing.Size(90, 45);
this.BtnOK.TabIndex = 1;
this.BtnOK.Text = "OK";
this.BtnOK.Click += new System.EventHandler(this.BtnOK_Click);
//
// BtnCancel
//
this.BtnCancel.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.BtnCancel.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.BtnCancel.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.BtnCancel.BorderWidth = 2;
this.BtnCancel.Font = new System.Drawing.Font("宋体", 12F);
this.BtnCancel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.BtnCancel.Location = new System.Drawing.Point(347, 270);
this.BtnCancel.Name = "BtnCancel";
this.BtnCancel.Padding = new System.Windows.Forms.Padding(3);
this.BtnCancel.Size = new System.Drawing.Size(90, 45);
this.BtnCancel.TabIndex = 2;
this.BtnCancel.Text = "Cancel";
this.BtnCancel.Click += new System.EventHandler(this.BtnCancel_Click);
//
// faceTextBox1
//
this.faceTextBox1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.faceTextBox1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.faceTextBox1.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.faceTextBox1.BorderWidth = 2;
this.faceTextBox1.Font = new System.Drawing.Font("宋体", 12F);
this.faceTextBox1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.faceTextBox1.Location = new System.Drawing.Point(11, 159);
this.faceTextBox1.MaxLength = 32767;
this.faceTextBox1.Name = "faceTextBox1";
this.faceTextBox1.Padding = new System.Windows.Forms.Padding(3);
this.faceTextBox1.SelectedText = "";
this.faceTextBox1.SelectionLength = 0;
this.faceTextBox1.SelectionStart = 0;
this.faceTextBox1.ShowDel = true;
this.faceTextBox1.ShowQuery = false;
this.faceTextBox1.Size = new System.Drawing.Size(426, 45);
this.faceTextBox1.TabIndex = 0;
this.faceTextBox1.Text = "faceTextBox1";
//
// faceLabel1
//
this.faceLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.faceLabel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.faceLabel1.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.faceLabel1.BorderWidth = 0;
this.faceLabel1.Font = new System.Drawing.Font("宋体", 12F);
this.faceLabel1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.faceLabel1.Location = new System.Drawing.Point(11, 55);
this.faceLabel1.Name = "faceLabel1";
this.faceLabel1.Padding = new System.Windows.Forms.Padding(3);
this.faceLabel1.Size = new System.Drawing.Size(426, 98);
this.faceLabel1.TabIndex = 11;
this.faceLabel1.Text = "faceLabel1";
this.faceLabel1.TextAlign = System.Drawing.ContentAlignment.BottomCenter;
//
// FaceInputBox
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(448, 326);
this.Controls.Add(this.faceLabel1);
this.Controls.Add(this.faceTextBox1);
this.Controls.Add(this.BtnOK);
this.Controls.Add(this.BtnCancel);
this.Controls.Add(this.ctlClose);
this.Location = new System.Drawing.Point(0, 0);
this.Name = "FaceInputBox";
this.Text = "FaceInputBox";
this.TitleFont = new System.Drawing.Font("宋体", 18F);
this.TitleHeight = 45;
this.Load += new System.EventHandler(this.FaceInputBox_Load);
this.ResumeLayout(false);
}
#endregion
private CtlClose ctlClose;
private FaceButton BtnOK;
private FaceButton BtnCancel;
private FaceTextBox faceTextBox1;
private FaceLabel faceLabel1;
}
}
\ No newline at end of file
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 Asa.FaceControl
{
public partial class FaceInputBox : FormBase
{
public FaceInputBox(string title, string text, string defaultValue = "")
{
InitializeComponent();
ctlClose.Click += CtlClose_Click;
CanResize = false;
Text = title;
faceLabel1.Text = text;
faceTextBox1.Text = defaultValue;
}
public string InputValue { private set; get; }
protected override void CalcSize()
{
base.CalcSize();
int n = 1;
if (ctlClose != null)
{
ctlClose.Size = new Size(60, TitleHeight - 5);
n += ctlClose.Width;
ctlClose.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
}
private void CtlClose_Click(object sender, EventArgs e)
{
Close();
}
private void BtnOK_Click(object sender, EventArgs e)
{
InputValue = faceTextBox1.Text;
DialogResult = DialogResult.OK;
}
private void BtnCancel_Click(object sender, EventArgs e)
{
InputValue = "";
DialogResult = DialogResult.Cancel;
}
private void FaceInputBox_Load(object sender, EventArgs e)
{
faceTextBox1.Focus();
}
}
}
<?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>
\ No newline at end of file

namespace Asa.FaceControl
{
partial class FaceMessageBox
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.ctlClose = new Asa.FaceControl.CtlClose();
this.BtnThree = new Asa.FaceControl.FaceButton();
this.BtnTwo = new Asa.FaceControl.FaceButton();
this.faceLabel1 = new Asa.FaceControl.FaceLabel();
this.BtnOne = new Asa.FaceControl.FaceButton();
this.SuspendLayout();
//
// ctlClose
//
this.ctlClose.Location = new System.Drawing.Point(53, 11);
this.ctlClose.Name = "ctlClose";
this.ctlClose.Size = new System.Drawing.Size(80, 23);
this.ctlClose.TabIndex = 3;
//
// BtnThree
//
this.BtnThree.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.BtnThree.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.BtnThree.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.BtnThree.BorderWidth = 2;
this.BtnThree.Font = new System.Drawing.Font("宋体", 12F);
this.BtnThree.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.BtnThree.HoldPress = false;
this.BtnThree.Location = new System.Drawing.Point(398, 276);
this.BtnThree.Name = "BtnThree";
this.BtnThree.Padding = new System.Windows.Forms.Padding(3);
this.BtnThree.Size = new System.Drawing.Size(90, 45);
this.BtnThree.TabIndex = 4;
this.BtnThree.Text = "Three";
//
// BtnTwo
//
this.BtnTwo.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.BtnTwo.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.BtnTwo.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.BtnTwo.BorderWidth = 2;
this.BtnTwo.Font = new System.Drawing.Font("宋体", 12F);
this.BtnTwo.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.BtnTwo.HoldPress = false;
this.BtnTwo.Location = new System.Drawing.Point(302, 276);
this.BtnTwo.Name = "BtnTwo";
this.BtnTwo.Padding = new System.Windows.Forms.Padding(3);
this.BtnTwo.Size = new System.Drawing.Size(90, 45);
this.BtnTwo.TabIndex = 5;
this.BtnTwo.Text = "Two";
//
// faceLabel1
//
this.faceLabel1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.faceLabel1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.faceLabel1.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.faceLabel1.BorderWidth = 0;
this.faceLabel1.Font = new System.Drawing.Font("宋体", 12F);
this.faceLabel1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.faceLabel1.Location = new System.Drawing.Point(11, 46);
this.faceLabel1.Name = "faceLabel1";
this.faceLabel1.Padding = new System.Windows.Forms.Padding(3);
this.faceLabel1.Size = new System.Drawing.Size(477, 224);
this.faceLabel1.TabIndex = 6;
this.faceLabel1.Text = "faceLabel1";
//
// BtnOne
//
this.BtnOne.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.BtnOne.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.BtnOne.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.BtnOne.BorderWidth = 2;
this.BtnOne.Font = new System.Drawing.Font("宋体", 12F);
this.BtnOne.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.BtnOne.HoldPress = false;
this.BtnOne.Location = new System.Drawing.Point(206, 276);
this.BtnOne.Name = "BtnOne";
this.BtnOne.Padding = new System.Windows.Forms.Padding(3);
this.BtnOne.Size = new System.Drawing.Size(90, 45);
this.BtnOne.TabIndex = 7;
this.BtnOne.Text = "One";
//
// FaceMessageBox
//
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.None;
this.ClientSize = new System.Drawing.Size(499, 332);
this.Controls.Add(this.BtnOne);
this.Controls.Add(this.faceLabel1);
this.Controls.Add(this.BtnTwo);
this.Controls.Add(this.BtnThree);
this.Controls.Add(this.ctlClose);
this.Location = new System.Drawing.Point(0, 0);
this.Name = "FaceMessageBox";
this.Text = "FaceFormDialog";
this.TitleFont = new System.Drawing.Font("宋体", 18F);
this.TitleHeight = 45;
this.ResumeLayout(false);
}
#endregion
private CtlClose ctlClose;
private FaceButton BtnThree;
private FaceButton BtnTwo;
private FaceLabel faceLabel1;
private FaceButton BtnOne;
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace Asa.FaceControl
{
public partial class FaceMessageBox : FormBase
{
private readonly Dictionary<MessageBoxButtons, Action> msgButton;
private readonly DialogResult[] dialog;
private readonly FaceButton[] button;
public FaceMessageBox(string title, string text, MessageBoxButtons button)
{
InitializeComponent();
ctlClose.Click += CtlClose_Click;
CanResize = false;
dialog = new DialogResult[3];
this.button = new FaceButton[3] { BtnOne, BtnTwo, BtnThree };
BtnOne.Click += BtnMessage_Click;
BtnTwo.Click += BtnMessage_Click;
BtnThree.Click += BtnMessage_Click;
msgButton = new Dictionary<MessageBoxButtons, Action>
{
{ MessageBoxButtons.OK, MsgOK },
{ MessageBoxButtons.OKCancel, MsgOKCancel },
{ MessageBoxButtons.AbortRetryIgnore, MsgAbortRetryIgnore },
{ MessageBoxButtons.YesNoCancel, MsgYesNoCancel },
{ MessageBoxButtons.YesNo, MsgYesNo },
{ MessageBoxButtons.RetryCancel, MsgRetryCancel }
};
Text = title;
faceLabel1.Text = text;
msgButton[button].Invoke();
}
protected override void CalcSize()
{
base.CalcSize();
int n = 1;
if (ctlClose != null)
{
ctlClose.Size = new Size(60, TitleHeight - 5);
n += ctlClose.Width;
ctlClose.Location = new Point(Width - BorderWidth - n, BorderWidth + 1);
ctlClose.Anchor = AnchorStyles.Top | AnchorStyles.Right;
}
}
private void MsgOK()
{
button[2].Text = "OK";
dialog[2] = DialogResult.OK;
button[0].Visible = button[1].Visible = false;
}
private void MsgOKCancel()
{
button[1].Text = "OK";
dialog[1] = DialogResult.OK;
button[2].Text = "Cancel";
dialog[2] = DialogResult.Cancel;
button[0].Visible = false;
}
private void MsgAbortRetryIgnore()
{
button[0].Text = "Abort";
dialog[0] = DialogResult.Abort;
button[1].Text = "Retry";
dialog[1] = DialogResult.Retry;
button[2].Text = "Ignore";
dialog[2] = DialogResult.Ignore;
}
private void MsgYesNoCancel()
{
button[0].Text = "Yes";
dialog[0] = DialogResult.Yes;
button[1].Text = "No";
dialog[1] = DialogResult.No;
button[2].Text = "Cancel";
dialog[2] = DialogResult.Cancel;
}
private void MsgYesNo()
{
button[1].Text = "Yes";
dialog[1] = DialogResult.Yes;
button[2].Text = "No";
dialog[2] = DialogResult.No;
button[0].Visible = false;
}
private void MsgRetryCancel()
{
button[1].Text = "Retry";
dialog[1] = DialogResult.Retry;
button[2].Text = "Cancel";
dialog[2] = DialogResult.Cancel;
button[0].Visible = false;
}
private void CtlClose_Click(object sender, EventArgs e)
{
Close();
}
private void BtnMessage_Click(object sender, EventArgs e)
{
FaceButton btn = sender as FaceButton;
int index = Array.FindIndex(button, s => s == btn);
if (index == -1) return;
DialogResult = dialog[index];
}
}
}
<?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>
\ No newline at end of file
using System;
using System.Xml;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
namespace Asa.FaceControl
{
/// <summary>
/// 多语言类
/// </summary>
public static class Language
{
private static XmlDocument xmlDoc;
private static string[] filePath; //XML文件的路径
private static int nameIndex = -1;
private static readonly Dictionary<string, string> dialogText = new();
private static readonly List<ClsLangForm> langForm = new();
/// <summary>
/// 语言名称
/// </summary>
public static string[] Name { private set; get; } = null;
/// <summary>
/// 加载语言路径
/// </summary>
/// <param name="path"></param>
public static void LoadPath(string path)
{
if (!System.IO.Directory.Exists(path))
System.IO.Directory.CreateDirectory(path);
filePath = System.IO.Directory.GetFiles(path, "*.xml");
xmlDoc = new XmlDocument();
Name = new string[filePath.Length];
for (int i = 0; i < filePath.Length; i++)
{
xmlDoc.Load(filePath[i]);
Name[i] = xmlDoc.LastChild.Attributes["Name"].Value;
}
}
/// <summary>
/// 加载语言
/// </summary>
/// <param name="name"></param>
public static void LoadLanguage(string name)
{
nameIndex = Array.FindIndex(Name, s => s == name);
if (nameIndex == -1) return;
LoadLanguage();
foreach (Form frm in Application.OpenForms)
{
if (frm is FormBase @base)
SetLanguage(@base);
}
}
/// <summary>
/// 对话框
/// </summary>
/// <param name="key"></param>
/// <returns></returns>
public static string Dialog(string key)
{
if (nameIndex == -1) return "";
if (dialogText.TryGetValue(key, out string value))
return value;
else
return "";
}
/// <summary>
/// 设置语言
/// </summary>
/// <param name="frm"></param>
public static void SetLanguage(FormBase frm)
{
if (nameIndex == -1) return;
int langIdx = langForm.FindIndex(s => s.FormLang.Name == frm.Name);
if (langIdx == -1) return;
frm.Text = langForm[langIdx].FormLang.Text;
frm.TitleFont = langForm[langIdx].FormLang.Font;
SetLang(langIdx, frm);
}
/// <summary>
/// 设置语言
/// </summary>
/// <param name="ctl"></param>
public static void SetLanguage(Control ctl)
{
if (nameIndex == -1) return;
int langIdx = langForm.FindIndex(s => s.FormLang.Name == ctl.Name);
if (langIdx == -1) return;
SetLang(langIdx, ctl);
}
///// <summary>
///// 语言索引
///// </summary>
//public static int Index
//{
// set
// {
// if (value > -1 && value < _file.Length)
// {
// _index = value;
// LoadLanguage();
// foreach (Form frm in Application.OpenForms)
// {
// if (frm is FormBase)
// SetLanguage((FormBase)frm);
// }
// }
// }
// get
// {
// return _index;
// }
//}
///// <summary>
///// 加载语言
///// </summary>
///// <param name="name"></param>
//public static void Load(string name)
//{
// int idx = Array.FindIndex(Name, s => s == name);
// Index = idx;
//}
///// <summary>
///// 设置语言
///// </summary>
///// <param name="frm"></param>
//public static void SetLanguage(Form frm)
//{
// int langIdx = langForm.FindIndex(s => s.FormLang.Name == frm.Name);
// if (langIdx == -1) return;
// //frm.Text = langForm[langIdx].FormLang.Text;
// //frm.TitleFont = langForm[langIdx].FormLang.Font;
// SetLang(langIdx, frm);
//}
private static void LoadLanguage()
{
xmlDoc.Load(filePath[nameIndex]);
XmlNode root = xmlDoc.LastChild;
langForm.Clear();
dialogText.Clear();
foreach (XmlNode node in root.ChildNodes)
{
if (node.Name == "Dialog")
{
foreach (XmlNode tt in node.ChildNodes)
dialogText.Add(tt.Name, tt.InnerText);
}
else
{
ClsLangForm lang = new();
lang.FormLang.Name = node.Name;
if (node.Attributes["Text"] != null) lang.FormLang.Text = node.Attributes["Text"].Value;
if (node.Attributes["Font"] != null) lang.FormLang.Font = ConvFont(node.Attributes["Font"].Value);
//if (node.Attributes["Tag"] != null) lang.FormLang.Tag = node.Attributes["Tag"].Value;
foreach (XmlNode tt in node.ChildNodes)
{
ClsLangText ll = new()
{
Name = tt.Name
};
if (tt.Attributes["Text"] != null) ll.Text = tt.Attributes["Text"].Value;
if (tt.Attributes["Font"] != null) ll.Font = ConvFont(tt.Attributes["Font"].Value);
//if (tt.Attributes["Tag"] != null) ll.Tag = tt.Attributes["Tag"].Value;
lang.ControlLang.Add(ll);
}
langForm.Add(lang);
}
}
}
private static void SetLang(int langIndex, Control ctl)
{
foreach (Control cc in ctl.Controls)
{
if (cc.Name == "") continue;
int idx = langForm[langIndex].ControlLang.FindIndex(s => s.Name == cc.Name);
if (idx > -1)
{
cc.Text = langForm[langIndex].ControlLang[idx].Text;
if (cc is FacePanel)
((FacePanel)cc).TitleFont = langForm[langIndex].ControlLang[idx].Font;
else
cc.Font = langForm[langIndex].ControlLang[idx].Font;
//cc.Tag = langForm[langIndex].ControlLang[idx].Tag;
}
if (cc.HasChildren)
SetLang(langIndex, cc);
}
}
/// <summary>
/// 转换字体
/// </summary>
/// <param name="s">格式:字体,字号,粗体,斜体</param>
/// <returns></returns>
private static Font ConvFont(string s)
{
string[] t = s.Split(',');
float emSize = Convert.ToSingle(t[1]);
FontStyle style = FontStyle.Regular;
if (t[2] == "B") style |= FontStyle.Bold;
if (t[3] == "I") style |= FontStyle.Italic;
Font font = new(t[0], emSize, style);
return font;
}
///// <summary>
///// 转换字体
///// </summary>
///// <param name="f">字体</param>
///// <returns></returns>
//private static string ConvFont(Font f)
//{
// string[] s = new string[4];
// s[0] = f.Name;
// s[1] = f.Size.ToString();
// if (f.Bold) s[2] = "B";
// if (f.Italic) s[3] = "I";
// return string.Join(",", s);
//}
private class ClsLangForm
{
public ClsLangText FormLang;
public List<ClsLangText> ControlLang;
public ClsLangForm()
{
FormLang = new ClsLangText();
ControlLang = new List<ClsLangText>();
}
}
private class ClsLangText
{
public string Name = "";
public string Text = "";
public Font Font = null;
//public static string Tag = "";
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace Asa.FaceControl
{
public static class API
{
[DllImport("user32")]
public static extern int ReleaseCapture();
[DllImport("user32")]
public static extern int SendMessage(IntPtr hwnd, int wMsg, int wParam, int lParam);
[DllImport("user32")]
public extern static int GetCaretBlinkTime();
[DllImport("user32.dll")]
public extern static bool GetCursorPos(out Point pt);
[DllImport("gdi32.dll")]
public static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSource, int xSrc, int ySrc, CopyPixelOperation rop);
[DllImport("gdi32.dll")]
public static extern IntPtr DeleteDC(IntPtr hDc);
[DllImport("gdi32.dll")]
public static extern IntPtr DeleteObject(IntPtr hDc);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);
[DllImport("gdi32.dll")]
public static extern IntPtr CreateCompatibleDC(IntPtr hdc);
[DllImport("gdi32.dll")]
public static extern IntPtr SelectObject(IntPtr hdc, IntPtr bmp);
[DllImport("user32.dll")]
public static extern IntPtr GetDesktopWindow();
[DllImport("user32.dll")]
public static extern IntPtr GetWindowDC(IntPtr ptr);
[DllImport("user32.dll")]
public static extern bool PrintWindow(IntPtr hwnd, IntPtr hdcBlt, UInt32 nFlags);
[DllImport("user32.dll")]
public static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);
public const int WM_SYSCOMMAND = 0x112;
public const int SC_MOVE = 0xF010;
public const int HTCAPTION = 0x2;
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Asa.FaceControl
{
public enum ControlShape
{
/// <summary>
/// 矩形
/// </summary>
Rectangle,
/// <summary>
/// 圆角矩形
/// </summary>
RoundRectangle,
/// <summary>
/// 椭圆
/// </summary>
Ellipse,
/// <summary>
/// 椭圆矩形
/// </summary>
EllipseRectangle,
/// <summary>
/// 圆形
/// </summary>
Circle
}
}
using System;
using System.Drawing;
namespace Asa.FaceControl
{
public class DarkThemeColor : IFaceThemeColor
{
public Color BACK { get; } = Color.FromArgb(20, 20, 20);
public Color FORE { get; } = Color.FromArgb(230, 230, 230);
public Color DOWN { get; } = Color.FromArgb(0, 110, 200);
public Color OVER { get; } = Color.FromArgb(70, 70, 70);
public Color BORDER_ENTER { get; } = Color.FromArgb(0, 130, 220);
public Color BORDER_LEAVE { get; } = Color.FromArgb(100, 100, 100);
public Color DISABLED { get; } = Color.FromArgb(100, 100, 100);
public Color SCROLL_BAR_BACK { get; } = Color.FromArgb(60, 60, 60);
public Color SCROLL_BAR_OVER { get; } = Color.FromArgb(110, 110, 110);
public Color SCROLL_BAR_DOWN { get; } = Color.FromArgb(0, 110, 200);
public Color LIST_LINE_1 { get; } = Color.FromArgb(50, 50, 50);
public Color LIST_LINE_2 { get; } = Color.FromArgb(30, 30, 30);
public string CONTROL_PARTS_FONT { get; } = "宋体";
public Color TITLE_BUTTON_FORE { get; } = Color.FromArgb(230, 230, 230);
public Color TITLE_CLOSE_BUTTON_BACK { get; } = Color.FromArgb(30, 30, 30);
public Color TITLE_CLOSE_BUTTON_OVER { get; } = Color.FromArgb(150, 50, 50);
public Color TITLE_CLOSE_BUTTON_DOWN { get; } = Color.FromArgb(240, 70, 90);
public Color TITLE_MIN_BUTTON_BACK { get; } = Color.FromArgb(30, 30, 30);
public Color TITLE_MIN_BUTTON_OVER { get; } = Color.FromArgb(80, 80, 80);
public Color TITLE_MIN_BUTTON_DOWN { get; } = Color.FromArgb(0, 122, 204);
public Color TITLE_MAX_BUTTON_BACK { get; } = Color.FromArgb(30, 30, 30);
public Color TITLE_MAX_BUTTON_OVER { get; } = Color.FromArgb(80, 80, 80);
public Color TITLE_MAX_BUTTON_DOWN { get; } = Color.FromArgb(0, 122, 204);
}
}
using System;
using System.Drawing;
namespace Asa.FaceControl
{
public interface IFaceThemeColor
{
public Color BACK { get; }
public Color FORE { get; }
public Color DOWN { get; }
public Color OVER { get; }
public Color BORDER_ENTER { get; }
public Color BORDER_LEAVE { get; }
public Color DISABLED { get; }
public Color SCROLL_BAR_BACK { get; }
public Color SCROLL_BAR_OVER { get; }
public Color SCROLL_BAR_DOWN { get; }
public Color LIST_LINE_1 { get; }
public Color LIST_LINE_2 { get; }
public string CONTROL_PARTS_FONT { get; }
public Color TITLE_BUTTON_FORE { get; }
public Color TITLE_CLOSE_BUTTON_BACK { get; }
public Color TITLE_CLOSE_BUTTON_OVER { get; }
public Color TITLE_CLOSE_BUTTON_DOWN { get; }
public Color TITLE_MIN_BUTTON_BACK { get; }
public Color TITLE_MIN_BUTTON_OVER { get; }
public Color TITLE_MIN_BUTTON_DOWN { get; }
public Color TITLE_MAX_BUTTON_BACK { get; }
public Color TITLE_MAX_BUTTON_OVER { get; }
public Color TITLE_MAX_BUTTON_DOWN { get; }
}
}
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("FaceControl")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("FaceControl")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// 将 ComVisible 设置为 false 会使此程序集中的类型
//对 COM 组件不可见。如果需要从 COM 访问此程序集中的类型
//请将此类型的 ComVisible 特性设置为 true。
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("bb46377e-cc9f-4ac2-9367-87503b59efe7")]
// 程序集的版本信息由下列四个值组成:
//
// 主版本
// 次版本
// 生成号
// 修订号
//
//可以指定所有这些值,也可以使用“生成号”和“修订号”的默认值
//通过使用 "*",如下所示:
[assembly: AssemblyVersion("1.0.*")]
//[assembly: AssemblyVersion("1.0.0.0")]
//[assembly: AssemblyFileVersion("1.0.0.0")]
//------------------------------------------------------------------------------
// <auto-generated>
// 此代码由工具生成。
// 运行时版本:4.0.30319.42000
//
// 对此文件的更改可能会导致不正确的行为,并且如果
// 重新生成代码,这些更改将会丢失。
// </auto-generated>
//------------------------------------------------------------------------------
namespace Asa.FaceControl {
using System;
/// <summary>
/// 一个强类型的资源类,用于查找本地化的字符串等。
/// </summary>
// 此类是由 StronglyTypedResourceBuilder
// 类通过类似于 ResGen 或 Visual Studio 的工具自动生成的。
// 若要添加或移除成员,请编辑 .ResX 文件,然后重新运行 ResGen
// (以 /str 作为命令选项),或重新生成 VS 项目。
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
internal class Resource1 {
private static global::System.Resources.ResourceManager resourceMan;
private static global::System.Globalization.CultureInfo resourceCulture;
[global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")]
internal Resource1() {
}
/// <summary>
/// 返回此类使用的缓存的 ResourceManager 实例。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Resources.ResourceManager ResourceManager {
get {
if (object.ReferenceEquals(resourceMan, null)) {
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Asa.FaceControl.Resource1", typeof(Resource1).Assembly);
resourceMan = temp;
}
return resourceMan;
}
}
/// <summary>
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写。
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture {
get {
return resourceCulture;
}
set {
resourceCulture = value;
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ArrowDown {
get {
object obj = ResourceManager.GetObject("ArrowDown", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ArrowUp {
get {
object obj = ResourceManager.GetObject("ArrowUp", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Delete {
get {
object obj = ResourceManager.GetObject("Delete", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap Query {
get {
object obj = ResourceManager.GetObject("Query", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ScrollDown {
get {
object obj = ResourceManager.GetObject("ScrollDown", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ScrollLeft {
get {
object obj = ResourceManager.GetObject("ScrollLeft", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ScrollRight {
get {
object obj = ResourceManager.GetObject("ScrollRight", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
/// <summary>
/// 查找 System.Drawing.Bitmap 类型的本地化资源。
/// </summary>
internal static System.Drawing.Bitmap ScrollUp {
get {
object obj = ResourceManager.GetObject("ScrollUp", resourceCulture);
return ((System.Drawing.Bitmap)(obj));
}
}
}
}
<?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>
<assembly alias="System.Windows.Forms" name="System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" />
<data name="ArrowDown" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ArrowDown.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ArrowUp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ArrowUp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Delete" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Delete.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="Query" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\Query.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ScrollDown" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ScrollDown.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ScrollLeft" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ScrollLeft.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ScrollRight" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ScrollRight.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
<data name="ScrollUp" type="System.Resources.ResXFileRef, System.Windows.Forms">
<value>Resources\ScrollUp.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a</value>
</data>
</root>
\ No newline at end of file
此文件类型无法预览
此文件的差异太大,无法显示。
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")]
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")]
C:\Neotel\Program_Beta\FaceControl\FaceControl\bin\Debug\Asa.Face.Control.dll
C:\Neotel\Program_Beta\FaceControl\FaceControl\bin\Debug\Asa.Face.Control.pdb
C:\Neotel\Program_Beta\FaceControl\FaceControl\bin\Debug\log4net.dll
C:\Neotel\Program_Beta\FaceControl\FaceControl\bin\Debug\log4net.xml
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.ControlBase.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FormBase.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceLabel.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceButton.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlClose.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlMax.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlMin.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceFormNormal.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\FaceControl.csproj.GenerateResource.cache
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\FaceControl.csproj.CoreCompileInputs.cache
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\FaceControl.csproj.CopyComplete
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.Face.Control.dll
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.Face.Control.pdb
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceMessageBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceTextBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlDel.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlQuery.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.Resource1.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceCheckBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceRadioBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceScrollBar.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlBar.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceListBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlScrollUp.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlScrollDown.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceComboBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlComboArrow.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlNumericDown.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlNumericUp.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceNumericUpDown.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FacePanel.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.PanelBase.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FacePictureBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceInputBox.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceFormFixed.resources
C:\Neotel\Program_Beta\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FacePasswordLock.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.Face.Control.dll
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.Face.Control.pdb
C:\Neotel\Program\FaceControl\FaceControl\bin\Debug\Asa.Face.Control.dll
C:\Neotel\Program\FaceControl\FaceControl\bin\Debug\Asa.Face.Control.pdb
C:\Neotel\Program\FaceControl\FaceControl\bin\Debug\log4net.dll
C:\Neotel\Program\FaceControl\FaceControl\bin\Debug\log4net.xml
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.ControlBase.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FormBase.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceLabel.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceButton.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceTextBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlDel.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlQuery.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceCheckBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceRadioBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlScrollUp.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlScrollDown.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceScrollBar.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlBar.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceListBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlComboArrow.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceComboBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlNumericDown.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlNumericUp.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceNumericUpDown.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FacePanel.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FacePictureBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FacePasswordLock.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceFormFixed.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceInputBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceMessageBox.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlClose.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlMax.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.CtlMin.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.FaceFormNormal.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.PanelBase.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\Asa.FaceControl.Resource1.resources
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\FaceControl.csproj.GenerateResource.cache
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\FaceControl.csproj.CoreCompileInputs.cache
C:\Neotel\Program\FaceControl\FaceControl\obj\Debug\FaceControl.csproj.CopyComplete
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="log4net" version="2.0.12" targetFramework="net461" />
</packages>
\ No newline at end of file
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2" />
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
\ No newline at end of file

namespace Test
{
partial class Form1
{
/// <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 Windows 窗体设计器生成的代码
/// <summary>
/// 设计器支持所需的方法 - 不要修改
/// 使用代码编辑器修改此方法的内容。
/// </summary>
private void InitializeComponent()
{
this.facePasswordLock1 = new Asa.FaceControl.FacePasswordLock();
this.SuspendLayout();
//
// facePasswordLock1
//
this.facePasswordLock1.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(20)))), ((int)(((byte)(20)))), ((int)(((byte)(20)))));
this.facePasswordLock1.BorderStyle = Asa.FaceControl.ControlShape.Rectangle;
this.facePasswordLock1.BorderWidth = 2;
this.facePasswordLock1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(230)))), ((int)(((byte)(230)))), ((int)(((byte)(230)))));
this.facePasswordLock1.Location = new System.Drawing.Point(201, 140);
this.facePasswordLock1.Name = "facePasswordLock1";
this.facePasswordLock1.Padding = new System.Windows.Forms.Padding(3);
this.facePasswordLock1.Size = new System.Drawing.Size(240, 240);
this.facePasswordLock1.TabIndex = 3;
this.facePasswordLock1.Text = "facePasswordLock1";
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(713, 470);
this.Controls.Add(this.facePasswordLock1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.Controls.SetChildIndex(this.facePasswordLock1, 0);
this.ResumeLayout(false);
}
#endregion
private Asa.FaceControl.FacePasswordLock facePasswordLock1;
}
}
......@@ -8,13 +8,19 @@ using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
namespace Test
{
public partial class Form1 : Form
public partial class Form1 : Asa.FaceControl.FaceFormNormal
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
}
}
<?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>
\ No newline at end of file
......@@ -4,7 +4,7 @@ using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
namespace Test
{
static class Program
{
......
......@@ -5,11 +5,11 @@ using System.Runtime.InteropServices;
// 有关程序集的一般信息由以下
// 控制。更改这些特性值可修改
// 与程序集关联的信息。
[assembly: AssemblyTitle("WindowsFormsApp1")]
[assembly: AssemblyTitle("Test")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WindowsFormsApp1")]
[assembly: AssemblyProduct("Test")]
[assembly: AssemblyCopyright("Copyright © 2021")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
......@@ -20,7 +20,7 @@ using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
// 如果此项目向 COM 公开,则下列 GUID 用于类型库的 ID
[assembly: Guid("ad9f4add-a002-4ced-8fff-bce1b07538b0")]
[assembly: Guid("543499f4-8839-47f3-ac66-27627b259238")]
// 程序集的版本信息由下列四个值组成:
//
......
......@@ -8,10 +8,9 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace WindowsFormsApp1.Properties
{
namespace Test.Properties
{
/// <summary>
/// 强类型资源类,用于查找本地化字符串等。
/// </summary>
......@@ -44,7 +43,7 @@ namespace WindowsFormsApp1.Properties
{
if ((resourceMan == null))
{
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("WindowsFormsApp1.Properties.Resources", typeof(Resources).Assembly);
global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("Test.Properties.Resources", typeof(Resources).Assembly);
resourceMan = temp;
}
return resourceMan;
......@@ -52,8 +51,8 @@ namespace WindowsFormsApp1.Properties
}
/// <summary>
/// 覆盖当前线程的 CurrentUICulture 属性
/// 使用此强类型的资源类的资源查找
/// 重写当前线程的 CurrentUICulture 属性,对
/// 使用此强类型资源类的所有资源查找执行重写
/// </summary>
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)]
internal static global::System.Globalization.CultureInfo Culture
......
......@@ -8,10 +8,9 @@
// </auto-generated>
//------------------------------------------------------------------------------
namespace WindowsFormsApp1.Properties
{
namespace Test.Properties
{
[global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()]
[global::System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "11.0.0.0")]
internal sealed partial class Settings : global::System.Configuration.ApplicationSettingsBase
......
......@@ -4,11 +4,11 @@
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}</ProjectGuid>
<ProjectGuid>{543499F4-8839-47F3-AC66-27627B259238}</ProjectGuid>
<OutputType>WinExe</OutputType>
<RootNamespace>WindowsFormsApp1</RootNamespace>
<AssemblyName>WindowsFormsApp1</AssemblyName>
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
<RootNamespace>Test</RootNamespace>
<AssemblyName>Test</AssemblyName>
<TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<Deterministic>true</Deterministic>
......@@ -54,6 +54,9 @@
</Compile>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<EmbeddedResource Include="Form1.resx">
<DependentUpon>Form1.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
......@@ -76,5 +79,11 @@
<ItemGroup>
<None Include="App.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\FaceControl\FaceControl.csproj">
<Project>{BB46377E-CC9F-4AC2-9367-87503B59EFE7}</Project>
<Name>FaceControl</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1" />
</startup>
</configuration>
\ No newline at end of file
此文件类型无法预览
// <autogenerated />
using System;
using System.Reflection;
[assembly: global::System.Runtime.Versioning.TargetFrameworkAttribute(".NETFramework,Version=v4.6.1", FrameworkDisplayName = ".NET Framework 4.6.1")]
此文件类型无法预览
425ec005916d6d76b5941830798bc3b56a3757ae
C:\Neotel\Program_Beta\FaceControl\Test\bin\Debug\Test.exe.config
C:\Neotel\Program_Beta\FaceControl\Test\bin\Debug\Test.exe
C:\Neotel\Program_Beta\FaceControl\Test\bin\Debug\Test.pdb
C:\Neotel\Program_Beta\FaceControl\Test\bin\Debug\Asa.Face.Control.dll
C:\Neotel\Program_Beta\FaceControl\Test\bin\Debug\Asa.Face.Control.pdb
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.csprojAssemblyReference.cache
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.Form1.resources
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.Properties.Resources.resources
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.csproj.GenerateResource.cache
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.csproj.CoreCompileInputs.cache
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.csproj.CopyComplete
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.exe
C:\Neotel\Program_Beta\FaceControl\Test\obj\Debug\Test.pdb
C:\Neotel\Program\FaceControl\Test\bin\Debug\Test.exe.config
C:\Neotel\Program\FaceControl\Test\bin\Debug\Test.exe
C:\Neotel\Program\FaceControl\Test\bin\Debug\Test.pdb
C:\Neotel\Program\FaceControl\Test\bin\Debug\Asa.Face.Control.dll
C:\Neotel\Program\FaceControl\Test\bin\Debug\Asa.Face.Control.pdb
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.csprojAssemblyReference.cache
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.Form1.resources
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.Properties.Resources.resources
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.csproj.GenerateResource.cache
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.csproj.CoreCompileInputs.cache
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.csproj.CopyComplete
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.exe
C:\Neotel\Program\FaceControl\Test\obj\Debug\Test.pdb
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
此文件的差异太大,无法显示。
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!