Commit a2a230ca 顾剑亮

upload

1 个父辈 c64e5714
正在显示 158 个修改的文件 包含 5 行增加4868 行删除
此文件类型无法预览
...@@ -3,9 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 ...@@ -3,9 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 16 # Visual Studio Version 16
VisualStudioVersion = 16.0.30523.141 VisualStudioVersion = 16.0.30523.141
MinimumVisualStudioVersion = 10.0.40219.1 MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FaceControl", "FaceControl\FaceControl.csproj", "{06F6C6E6-02F6-4134-945A-BE51BEEF58A4}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsFormsApp1", "WindowsFormsApp1\WindowsFormsApp1.csproj", "{AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Test", "Test\Test.csproj", "{30CC76C8-F637-4323-BD65-EFE963DE17E8}"
EndProject EndProject
Global Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution GlobalSection(SolutionConfigurationPlatforms) = preSolution
...@@ -13,14 +11,10 @@ Global ...@@ -13,14 +11,10 @@ Global
Release|Any CPU = Release|Any CPU Release|Any CPU = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution GlobalSection(ProjectConfigurationPlatforms) = postSolution
{06F6C6E6-02F6-4134-945A-BE51BEEF58A4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{06F6C6E6-02F6-4134-945A-BE51BEEF58A4}.Debug|Any CPU.Build.0 = Debug|Any CPU {AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{06F6C6E6-02F6-4134-945A-BE51BEEF58A4}.Release|Any CPU.ActiveCfg = Release|Any CPU {AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{06F6C6E6-02F6-4134-945A-BE51BEEF58A4}.Release|Any CPU.Build.0 = Release|Any CPU {AD9F4ADD-A002-4CED-8FFF-BCE1B07538B0}.Release|Any CPU.Build.0 = Release|Any CPU
{30CC76C8-F637-4323-BD65-EFE963DE17E8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{30CC76C8-F637-4323-BD65-EFE963DE17E8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{30CC76C8-F637-4323-BD65-EFE963DE17E8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{30CC76C8-F637-4323-BD65-EFE963DE17E8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection EndGlobalSection
GlobalSection(SolutionProperties) = preSolution GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE HideSolutionNode = FALSE
......
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text;
using System.Threading.Tasks;
namespace 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;
}
}
namespace 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.Name = "ControlBase";
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.Resize += new System.EventHandler(this.ControlBase_Resize);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
namespace FaceControl
{
public partial class ControlBase : UserControl
{
private bool _inside = false;
private int _borderW = 2;
private HorizontalAlignment _textAlign = HorizontalAlignment.Center;
private Model.ButtonShape _shape = Model.ButtonShape.Rectangle;
internal Theme.IFaceTheme theme;
internal RectangleF borderRect;
internal Pen borderInsidePen;
internal Pen borderOutsidePen;
public ControlBase()
{
InitializeComponent();
AutoScaleMode = AutoScaleMode.None;
Margin = new Padding(3);
theme = new Theme.DarkTheme();
BackColor = theme.BACK_COLOR;
ForeColor = theme.FORE_COLOR;
}
//[Browsable(true), Category("属性已更改"), Description("在控件上更改Text属性的值时引发的事件")]
//public new event EventHandler TextChanged;
#region 属性
[Browsable(false)]
public new AutoScaleMode AutoScaleMode { set => base.AutoScaleMode = value; get => base.AutoScaleMode; }
[Browsable(false)]
public override bool AutoSize { get => base.AutoSize; set => base.AutoSize = value; }
[Browsable(false)]
public new AutoSizeMode AutoSizeMode { get => base.AutoSizeMode; set => base.AutoSizeMode = value; }
/// <summary>
/// 鼠标光标在控件里面
/// </summary>
[Browsable(false)]
public bool CursorInside
{
set
{
if (_inside != value)
{
if (Enabled)
{
_inside = value;
Refresh();
}
}
}
get
{
return _inside;
}
}
[Browsable(false)]
internal bool AllowHideDrop { set; get; } = true;
[Browsable(true), Category("外观"), Description("控件周围的边框大小"), DefaultValue(2)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int BorderWidth
{
set
{
if (value < 0)
_borderW = 0;
else
_borderW = value;
CalcSize();
Refresh();
}
get
{
return _borderW;
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本")]
[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("用于显示控件中文本的字体")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Font Font
{
get => base.Font;
set
{
base.Font = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("行为"), Description("提示是否已启用该控件"), DefaultValue(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new bool Enabled
{
get => base.Enabled;
set
{
base.Enabled = value;
Refresh();
}
}
[Browsable(true), Category("外观"), Description("组件的背景色"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Color BackColor
{
get => base.BackColor;
set
{
base.BackColor = value;
Refresh();
}
}
[Browsable(true), Category("外观"), Description("组件的前景色,用于显示文本"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Color ForeColor
{
get => base.ForeColor;
set
{
base.ForeColor = value;
Refresh();
}
}
[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(Model.ButtonShape.Rectangle)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Model.ButtonShape FaceShape
{
get => _shape;
set
{
_shape = value;
CalcSize();
Refresh();
}
}
#endregion
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()
{
borderRect = new RectangleF(_borderW / 2f, _borderW / 2f, Width - _borderW - 1, Height - _borderW - 1);
borderInsidePen = new Pen(theme.BORDER_COLOR, _borderW);
borderOutsidePen = new Pen(theme.LOST_FOCUS_COLOR, _borderW);
}
protected virtual void DrawEnabled(Graphics g)
{
}
protected virtual void DrawDisabled(Graphics g)
{
}
internal virtual void HideDrop()
{
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) // 禁掉清除背景消息
return;
//System.Diagnostics.Debug.Print("Message: " + m.Msg);
base.WndProc(ref m);
}
private void ControlBase_Load(object sender, EventArgs e)
{
AutoScaleMode = AutoScaleMode.None;
theme = new Theme.DarkTheme();
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(theme.BACK_COLOR); //背景
if (Enabled)
DrawEnabled(g);
else
DrawDisabled(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;
}
private void ControlBase_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (!AllowHideDrop) return;
if (TopLevelControl is FormBase @base)
@base.HideDrop(Handle);
}
}
}
}
<?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 \ 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;
using System.Drawing.Drawing2D;
namespace FaceControl
{
public partial class PanelBase : Panel
{
private bool _inside = false;
private int _borderW = 2;
private HorizontalAlignment _textAlign = HorizontalAlignment.Center;
private Model.ButtonShape _shape = Model.ButtonShape.Rectangle;
private Font _font = new Font("宋体", 9f);
internal Theme.IFaceTheme theme;
internal RectangleF borderRect;
internal Pen borderInsidePen;
internal Pen borderOutsidePen;
public PanelBase()
{
InitializeComponent();
theme = new Theme.DarkTheme();
Resize += PanelBase_Resize;
Paint += PanelBase_Paint;
MouseDown += PanelBase_MouseDown;
MouseEnter += PanelBase_MouseEnter;
MouseLeave += PanelBase_MouseLeave;
theme = new Theme.DarkTheme();
BackColor = theme.BACK_COLOR;
ForeColor = theme.FORE_COLOR;
}
#region 属性
[Browsable(false)]
public override bool AutoSize { get => base.AutoSize; set => base.AutoSize = value; }
[Browsable(false)]
public new AutoSizeMode AutoSizeMode { get => base.AutoSizeMode; set => base.AutoSizeMode = value; }
[Browsable(false)]
public new BorderStyle BorderStyle { get => base.BorderStyle; set => base.BorderStyle = value; }
[Browsable(false)]
public override Font Font { get => base.Font; set => base.Font = value; }
/// <summary>
/// 鼠标光标在控件里面
/// </summary>
[Browsable(false)]
public bool CursorInside
{
set
{
if (_inside != value)
{
if (Enabled)
{
_inside = value;
Refresh();
}
}
}
get
{
return _inside;
}
}
[Browsable(true), Category("外观"), Description("控件周围的边框大小"), DefaultValue(2)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int BorderWidth
{
set
{
if (value < 0)
_borderW = 0;
else
_borderW = value;
CalcSize();
Refresh();
}
get
{
return _borderW;
}
}
[Browsable(true), Category("外观"), Description("与控件关联的文本")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override string Text
{
get => base.Text;
set
{
base.Text = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("用于显示控件中文本的字体")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Font TitleFont
{
get => _font;
set
{
_font = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("行为"), Description("提示是否已启用该控件"), DefaultValue(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public new bool Enabled
{
get => base.Enabled;
set
{
base.Enabled = value;
Refresh();
}
}
[Browsable(true), Category("外观"), Description("组件的背景色"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Color BackColor
{
get => base.BackColor;
set
{
base.BackColor = value;
Refresh();
}
}
[Browsable(true), Category("外观"), Description("组件的前景色,用于显示文本"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public override Color ForeColor
{
get => base.ForeColor;
set
{
base.ForeColor = value;
Refresh();
}
}
[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(Model.ButtonShape.Rectangle)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Model.ButtonShape FaceShape
{
get => _shape;
set
{
_shape = value;
CalcSize();
Refresh();
}
}
#endregion
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()
{
borderRect = new RectangleF(_borderW / 2f, _borderW / 2f, Width - _borderW - 1, Height - _borderW - 1);
borderInsidePen = new Pen(theme.BORDER_COLOR, _borderW);
borderOutsidePen = new Pen(theme.LOST_FOCUS_COLOR, _borderW);
}
protected virtual void DrawEnabled(Graphics g)
{
}
protected virtual void DrawDisabled(Graphics g)
{
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0014) // 禁掉清除背景消息
return;
base.WndProc(ref m);
}
//private void PanelBase_Load(object sender, EventArgs e)
//{
// theme = new Theme.DarkTheme();
// CalcSize();
// Refresh();
//}
private void PanelBase_Resize(object sender, EventArgs e)
{
CalcSize();
Refresh();
}
private void PanelBase_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(theme.BACK_COLOR); //背景
if (Enabled)
DrawEnabled(g);
else
DrawDisabled(g);
bg.Render();
bg.Dispose();
}
private void PanelBase_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
if (TopLevelControl is FormBase @base)
{
@base.HideDrop(Handle);
}
}
}
private void PanelBase_MouseEnter(object sender, EventArgs e)
{
CursorInside = true;
}
private void PanelBase_MouseLeave(object sender, EventArgs e)
{
CursorInside = false;
}
}
}

namespace 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.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceButton";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceButton_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceButton_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceButton_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace FaceControl
{
partial class FaceButtonGroup
{
/// <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();
//
// FaceButtonGroup
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceButtonGroup";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceButtonGroup_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceButtonGroup_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceButtonGroup_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FaceButtonGroup : ControlBase
{
private bool mouseDown = false;
private int buttonOverIndex = -1;
private RectangleF[] textRect;
private RectangleF[] buttonRect;
private GraphicsPath borderPath = new GraphicsPath();
public FaceButtonGroup()
{
InitializeComponent();
}
#region 事件
[Browsable(true), Category("操作"), Description("单击组件时发生")]
public new event EventHandler Click;
#endregion
#region 属性
[Browsable(false)]
public int SelectedIndex
{
get => buttonOverIndex;
set
{
if (value > -1 && value < buttonRect.Length)
{
buttonOverIndex = value;
Click?.Invoke(this, new EventArgs());
}
}
}
[Browsable(false)]
public string SelectedText
{
get
{
if (buttonOverIndex == -1) return "";
string[] s = Text.Split(',');
return s[buttonOverIndex];
}
}
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
//控件边框
if (CursorInside && buttonOverIndex > -1)
{
if (mouseDown)
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), buttonRect[buttonOverIndex]); //按下
else
g.FillRectangle(new SolidBrush(theme.OVER_COLOR), buttonRect[buttonOverIndex]); //经过
Region reg = new Region(new Rectangle(0, 0, Width, Height));
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(theme.BACK_COLOR), reg);
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
}
else
{
buttonOverIndex = -1;
g.FillPath(new SolidBrush(BackColor), borderPath);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
}
//文字
string[] s = Text.Split(',');
for (int i = 0; i < s.Length; i++)
g.DrawString(s[i], Font, new SolidBrush(ForeColor), textRect[i]);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//控件边框
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//文字
string[] s = Text.Split(',');
for (int i = 0; i < s.Length; i++)
g.DrawString(s[i], Font, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect[i]);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
Graphics g = CreateGraphics();
string[] s = Text.Split(',');
buttonRect = new RectangleF[s.Length];
textRect = new RectangleF[s.Length];
float w = (Width - BorderWidth - BorderWidth) / (float)s.Length;
float h = Height - BorderWidth - BorderWidth;
for (int i = 0; i < s.Length; i++)
{
buttonRect[i] = new RectangleF(BorderWidth + w * i, BorderWidth, w, h);
SizeF sf = g.MeasureString(s[i], Font);
textRect[i] = new RectangleF(0, (h - sf.Height) / 2f, sf.Width, sf.Height);
switch (TextAlign)
{
case HorizontalAlignment.Left:
textRect[i].X = buttonRect[i].X;
break;
case HorizontalAlignment.Center:
textRect[i].X = buttonRect[i].X + (buttonRect[i].Width - sf.Width) / 2f;
break;
case HorizontalAlignment.Right:
textRect[i].X = buttonRect[i].X + buttonRect[i].Width - sf.Width;
break;
}
}
}
private void FaceButtonGroup_MouseDown(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
mouseDown = true;
Refresh();
}
}
private void FaceButtonGroup_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
mouseDown = false;
Refresh();
Click?.Invoke(this, new EventArgs());
}
}
private void FaceButtonGroup_MouseMove(object sender, MouseEventArgs e)
{
buttonOverIndex = -1;
for (int i = 0; i < buttonRect.Length; i++)
{
if (buttonRect[i].Contains(e.Location))
{
buttonOverIndex = i;
break;
}
}
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 \ No newline at end of file

namespace FaceControl
{
partial class FaceCheck
{
/// <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();
//
// FaceCheck
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceCheck";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceCheck_MouseDown);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceCheck_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("CheckedChanged")]
public partial class FaceCheck : ControlBase
{
private bool mouseDown = false;
private RectangleF checkOutRect = new RectangleF();
private RectangleF checkInRect = new RectangleF();
private RectangleF textRect = new RectangleF();
private GraphicsPath borderPath = new GraphicsPath();
private bool _check = false;
private int _checkWidth = 18;
private const int SPACE = 6; //图片与文字的间隔
public FaceCheck()
{
InitializeComponent();
}
#region 事件
[Browsable(true), Category("杂项"), Description("当checked属性更改值时发生")]
public event EventHandler CheckedChanged;
#endregion
#region 属性
[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;
}
}
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
//控件边框
if (CursorInside)
{
if (_check)
{
if (mouseDown)
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), checkOutRect);
else
g.FillRectangle(new SolidBrush(ForeColor), checkOutRect);
}
else
{
if (mouseDown)
g.FillRectangle(new SolidBrush(ForeColor), checkOutRect);
else
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), checkOutRect);
}
g.FillRectangle(new SolidBrush(theme.BACK_COLOR), checkInRect);
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
}
else
{
g.FillPath(new SolidBrush(BackColor), borderPath);
if (_check)
{
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), checkOutRect);
}
else
{
g.FillRectangle(new SolidBrush(ForeColor), checkOutRect);
}
g.FillRectangle(new SolidBrush(theme.BACK_COLOR), checkInRect);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
}
//开关圆点
//if (_check)
// g.FillRectangle(new SolidBrush(ForeColor), checkPoint);
if (_check)
{
g.DrawLine(new Pen(ForeColor, 2), checkInRect.X, checkInRect.Y + checkInRect.Height / 2f,
checkInRect.X + checkInRect.Width / 3f, checkInRect.Bottom);
g.DrawLine(new Pen(ForeColor, 2), checkInRect.X + checkInRect.Width / 3f, checkInRect.Bottom,
checkInRect.Right, checkInRect.Y);
}
//文字
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//控件边框
g.FillRectangle(new SolidBrush(theme.OVER_COLOR), checkOutRect);
g.FillRectangle(new SolidBrush(theme.BACK_COLOR), checkInRect);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//开关圆点
if (_check)
{
//g.FillRectangle(new SolidBrush(theme.OVER_COLOR), checkPoint);
g.DrawLine(new Pen(theme.OVER_COLOR, 2), checkInRect.X, checkInRect.Y + checkInRect.Height / 2f,
checkInRect.X + checkInRect.Width / 3f, checkInRect.Bottom);
g.DrawLine(new Pen(theme.OVER_COLOR, 2), checkInRect.X + checkInRect.Width / 3f, checkInRect.Bottom,
checkInRect.Right, checkInRect.Y);
}
//文字
g.DrawString(Text, Font, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
Graphics g = CreateGraphics();
SizeF sf = g.MeasureString(Text, Font);
checkOutRect = new RectangleF(0, (Height - _checkWidth) / 2f, _checkWidth, _checkWidth);
textRect = new RectangleF(0, (Height - sf.Height) / 2f, sf.Width, sf.Height);
float x;
switch (TextAlign)
{
case HorizontalAlignment.Left:
x = BorderWidth;
checkOutRect.X = x;
x += _checkWidth + SPACE;
textRect.X = x;
break;
case HorizontalAlignment.Center:
x = (Width - sf.Width - _checkWidth - SPACE) / 2f;
checkOutRect.X = x;
x += _checkWidth + SPACE;
textRect.X = x;
break;
case HorizontalAlignment.Right:
x = Width - BorderWidth - sf.Width;
textRect.X = x;
x -= (SPACE + _checkWidth);
checkOutRect.X = x;
break;
}
float w = _checkWidth / 6f;
checkInRect = new RectangleF(checkOutRect.X + w, checkOutRect.Y + w, w * 4, w * 4);
//checkPoint = new RectangleF(checkOutRect.X + w * 2, checkOutRect.Y + w * 2, w * 2, w * 2);
}
private void FaceCheck_MouseDown(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
mouseDown = true;
_check = !_check;
Refresh();
}
}
private void FaceCheck_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
mouseDown = false;
Refresh();
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 \ No newline at end of file

namespace FaceControl
{
partial class FaceCheckGroup
{
/// <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();
//
// FaceCheckGroup
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceCheckGroup";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceRadioGroup_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceRadioGroup_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceRadioGroup_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
[DefaultProperty("SelectedIndex")]
[DefaultEvent("CheckedChanged")]
public partial class FaceCheckGroup : ControlBase
{
private int buttonOverIndex = -1;
private List<int> buttonDownIndex;
private RectangleF[] textRect;
private RectangleF[] buttonRect;
private GraphicsPath borderPath = new GraphicsPath();
public FaceCheckGroup()
{
InitializeComponent();
buttonDownIndex = new List<int>();
}
#region 事件
[Browsable(true), Category("杂项"), Description("当checked属性更改值时发生")]
public event EventHandler CheckedChanged;
#endregion
#region 属性
[Browsable(false)]
public int[] SelectedIndex { get { return buttonDownIndex.ToArray(); } }
[Browsable(false)]
public string[] SelectedText
{
get
{
string[] s = Text.Split(',');
string[] rtn = new string[buttonDownIndex.Count];
for (int i = 0; i < rtn.Length; i++)
rtn[i] = s[buttonDownIndex[i]];
return rtn;
}
}
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
//控件边框
if (CursorInside && buttonOverIndex > -1)
{
for (int i = 0; i < buttonDownIndex.Count; i++)
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), buttonRect[buttonDownIndex[i]]);
int index = buttonDownIndex.FindIndex(s => s == buttonOverIndex);
if (index == -1)
g.FillRectangle(new SolidBrush(theme.OVER_COLOR), buttonRect[buttonOverIndex]); //经过
Region reg = new Region(new Rectangle(0, 0, Width, Height));
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(theme.BACK_COLOR), reg);
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
}
else
{
buttonOverIndex = -1;
g.FillPath(new SolidBrush(BackColor), borderPath);
for (int i = 0; i < buttonDownIndex.Count; i++)
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), buttonRect[buttonDownIndex[i]]);
Region reg = new Region(new Rectangle(0, 0, Width, Height));
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(theme.BACK_COLOR), reg);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
}
//文字
string[] s = Text.Split(',');
for (int i = 0; i < s.Length; i++)
g.DrawString(s[i], Font, new SolidBrush(ForeColor), textRect[i]);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//控件边框
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//文字
string[] s = Text.Split(',');
for (int i = 0; i < s.Length; i++)
g.DrawString(s[i], Font, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect[i]);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
Graphics g = CreateGraphics();
string[] s = Text.Split(',');
buttonRect = new RectangleF[s.Length];
textRect = new RectangleF[s.Length];
float w = (Width - BorderWidth - BorderWidth) / (float)s.Length;
float h = Height - BorderWidth - BorderWidth;
for (int i = 0; i < s.Length; i++)
{
buttonRect[i] = new RectangleF(BorderWidth + w * i, BorderWidth, w, h);
SizeF sf = g.MeasureString(s[i], Font);
textRect[i] = new RectangleF(0, (h - sf.Height) / 2f, sf.Width, sf.Height);
switch (TextAlign)
{
case HorizontalAlignment.Left:
textRect[i].X = buttonRect[i].X;
break;
case HorizontalAlignment.Center:
textRect[i].X = buttonRect[i].X + (buttonRect[i].Width - sf.Width) / 2f;
break;
case HorizontalAlignment.Right:
textRect[i].X = buttonRect[i].X + buttonRect[i].Width - sf.Width;
break;
}
}
}
private void FaceRadioGroup_MouseDown(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
int index = buttonDownIndex.FindIndex(s => s == buttonOverIndex);
if (index == -1)
buttonDownIndex.Add(buttonOverIndex);
else
buttonDownIndex.RemoveAt(index);
Refresh();
}
}
private void FaceRadioGroup_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
Refresh();
CheckedChanged?.Invoke(this, new EventArgs());
}
}
private void FaceRadioGroup_MouseMove(object sender, MouseEventArgs e)
{
buttonOverIndex = -1;
for (int i = 0; i < buttonRect.Length; i++)
{
if (buttonRect[i].Contains(e.Location))
{
buttonOverIndex = i;
break;
}
}
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 \ No newline at end of file

namespace FaceControl
{
partial class FaceCombo
{
/// <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();
//
// FaceCombo
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceCombo";
this.Size = new System.Drawing.Size(130, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceText_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceText_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceText_MouseUp);
this.Resize += new System.EventHandler(this.FaceText_Resize);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace FaceControl
{
partial class FaceImageShow
{
/// <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();
//
// FaceImageShow
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceImageShow";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceImageShow_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceImageShow_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceImageShow_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace 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.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceLabel";
this.Size = new System.Drawing.Size(85, 45);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceLabel_MouseMove);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
[DefaultProperty("Text")]
[DefaultEvent("Click")]
public partial class FaceLabel : ControlBase
{
private bool buttonOver = false;
private RectangleF imgRect = new RectangleF();
private RectangleF textRect = new RectangleF();
private GraphicsPath borderPath = new GraphicsPath();
private Bitmap _img = null;
private Size _imgSize = new Size();
private const int SPACE = 6; //图片与文字的间隔
public FaceLabel()
{
InitializeComponent();
}
#region 事件
[Browsable(true), Category("操作"), Description("单击组件时发生")]
public new event EventHandler Click;
#endregion
#region 属性
[Browsable(true), Category("外观"), Description("控件上显示的图像"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Bitmap Image
{
get => _img;
set
{
_img = value;
if (_img == null)
ImageSize = new Size();
else
ImageSize = _img.Size;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("控件上显示的图像的大小")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Size ImageSize
{
get => _imgSize;
set
{
_imgSize = value;
CalcSize();
Refresh();
}
}
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
g.FillPath(new SolidBrush(BackColor), borderPath);
//控件边框
if (CursorInside && buttonOver)
{
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
}
else
{
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
}
//图标
if (_img != null)
g.DrawImage(_img, imgRect, new RectangleF(0, 0, _img.Width, _img.Height), GraphicsUnit.Pixel);
//文字
StringFormat format = StringFormat.GenericTypographic;
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect, format);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//控件边框
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//图标
if (_img != null)
g.DrawImage(_img, imgRect, new RectangleF(0, 0, _img.Width, _img.Height), GraphicsUnit.Pixel);
//文字
g.DrawString(Text, Font, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
imgRect = new RectangleF(0, (Height - _imgSize.Height) / 2f, _imgSize.Width, _imgSize.Height);
Graphics g = CreateGraphics();
StringFormat format = StringFormat.GenericTypographic;
format.FormatFlags |= StringFormatFlags.MeasureTrailingSpaces;
SizeF sf = g.MeasureString(Text, Font, (int)borderRect.Width, format);
float w = Convert.ToSingle(Math.Ceiling(sf.Width));
float h = Convert.ToSingle(Math.Ceiling(sf.Height));
textRect = new RectangleF(0, (Height - h) / 2f, w, h);
float x;
switch (TextAlign)
{
case HorizontalAlignment.Left:
x = BorderWidth;
if (_img != null)
{
imgRect.X = x;
x += _imgSize.Width + SPACE;
}
textRect.X = x;
break;
case HorizontalAlignment.Center:
if (_img != null)
{
x = (Width - w - _imgSize.Width - SPACE) / 2f;
imgRect.X = x;
x += _imgSize.Width + SPACE;
}
else
{
x = (Width - w) / 2f;
}
textRect.X = x;
break;
case HorizontalAlignment.Right:
x = Width - BorderWidth - w;
textRect.X = x;
if (_img != null)
{
x -= (SPACE + _imgSize.Width);
imgRect.X = x;
}
break;
}
}
private void FaceLabel_MouseMove(object sender, MouseEventArgs e)
{
buttonOver = borderPath.IsVisible(e.Location);
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 \ No newline at end of file

namespace FaceControl
{
partial class FaceList
{
/// <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();
//
// FaceList
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceList";
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceButtonGroup_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceButtonGroup_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceButtonGroup_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace FaceControl
{
partial class FaceLock
{
/// <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();
//
// FaceLock
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceLock";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceLock_MouseDown);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceLock_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
public partial class FaceLock : ControlBase
{
//private bool mouseDown = false;
//private RectangleF checkOutRect = new RectangleF();
//private RectangleF checkInRect = new RectangleF();
private GraphicsPath lockPath = new GraphicsPath();
private RectangleF textRect = new RectangleF();
private GraphicsPath borderPath = new GraphicsPath();
private bool _lock = true;
private int _lockWidth = 20;
private const int SPACE = 6; //图片与文字的间隔
public FaceLock()
{
InitializeComponent();
}
#region 事件
[Browsable(true), Category("杂项"), Description("当LockState属性更改值时发生")]
public event EventHandler LockStateChanged;
#endregion
#region 属性
[Browsable(true), Category("外观"), Description("控件上锁按钮的宽度"), DefaultValue(20)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public int LockWidth
{
get => _lockWidth;
set
{
_lockWidth = value;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("锁按钮是否已锁上"), DefaultValue(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public bool LockState
{
set
{
if (_lock != value)
{
_lock = value;
CalcSize();
Refresh();
}
//CheckedChanged?.Invoke(this, new EventArgs());
}
get
{
return _lock;
}
}
[Browsable(false)]
public string Password { set; get; } = "";
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
//控件边框
if (CursorInside)
{
g.DrawPath(new Pen(theme.DOWN_COLOR, 2), lockPath);
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
}
else
{
if (_lock)
g.DrawPath(new Pen(ForeColor, 2), lockPath);
else
g.DrawPath(new Pen(theme.DOWN_COLOR, 2), lockPath);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
}
//文字
g.DrawString(Text, Font, new SolidBrush(ForeColor), textRect);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//控件边框
g.DrawPath(new Pen(theme.LOST_FOCUS_COLOR, 2), lockPath);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//文字
g.DrawString(Text, Font, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
Graphics g = CreateGraphics();
SizeF sf = g.MeasureString(Text, Font);
RectangleF rect = new RectangleF(0, (Height - _lockWidth) / 2f, _lockWidth, _lockWidth);
textRect = new RectangleF(0, (Height - sf.Height) / 2f, sf.Width, sf.Height);
float x;
switch (TextAlign)
{
case HorizontalAlignment.Left:
x = BorderWidth;
rect.X = x;
x += _lockWidth + SPACE;
textRect.X = x;
break;
case HorizontalAlignment.Center:
x = (Width - sf.Width - _lockWidth - SPACE) / 2f;
rect.X = x;
x += _lockWidth + SPACE;
textRect.X = x;
break;
case HorizontalAlignment.Right:
x = Width - BorderWidth - sf.Width;
textRect.X = x;
x -= (SPACE + _lockWidth);
rect.X = x;
break;
}
if (_lock)
lockPath = Shape.Lock(rect);
else
lockPath = Shape.Unlock(rect);
}
private void FaceLock_MouseDown(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
//_lock = !_lock;
//CalcTextLocation();
//Refresh();
}
}
private void FaceLock_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
if (_lock)
{
FormInput frm = new FormInput("LOCK", "PASSWORD", "");
DialogResult dr = frm.ShowDialog();
if (dr == DialogResult.OK)
{
if (frm.Msg == Password)
_lock = false;
}
}
else
{
_lock = true;
}
CalcTextLocation();
Refresh();
LockStateChanged?.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 \ No newline at end of file

namespace FaceControl
{
partial class FaceNumeric
{
/// <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();
//
// FaceNumeric
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceNumeric";
this.Size = new System.Drawing.Size(130, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceNumeric_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceNumeric_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceNumeric_MouseUp);
this.Resize += new System.EventHandler(this.FaceNumeric_Resize);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace 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()
{
components = new System.ComponentModel.Container();
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
[DefaultProperty("Image")]
public partial class FacePanel : PanelBase
{
private bool buttonOver = false;
private RectangleF imgRect = new RectangleF();
private RectangleF textRect = new RectangleF();
private GraphicsPath borderPath = new GraphicsPath();
private Bitmap _img = null;
private Size _imgSize = new Size();
private int _textHeight = 28;
private bool _showText = true;
private const int SPACE = 6; //图片与文字的间隔
public FacePanel()
{
InitializeComponent();
MouseMove += FaceButton_MouseMove;
}
#region 属性
[Browsable(true), Category("外观"), Description("控件上显示的图像"), DefaultValue(null)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Bitmap Image
{
get => _img;
set
{
_img = value;
if (_img == null)
ImageSize = new Size();
else
ImageSize = _img.Size;
CalcSize();
Refresh();
}
}
[Browsable(true), Category("外观"), Description("控件上显示的图像的大小")]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public Size ImageSize
{
get => _imgSize;
set
{
_imgSize = 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();
}
}
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
if (_showText)
{
Region reg = new Region(borderPath);
reg.Intersect(new RectangleF(0, borderRect.Y, Width, _textHeight));
g.FillRegion(new SolidBrush(theme.DOWN_COLOR), reg);
//文字
g.DrawString(Text, TitleFont, new SolidBrush(ForeColor), textRect);
}
//控件边框
//if (CursorInside && buttonOver)
//{
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
//}
//else
//{
// if (BorderWidth > 0)
// g.DrawPath(borderOutsidePen, borderPath);
//}
//图标
if (_img != null)
g.DrawImage(_img, imgRect, new RectangleF(0, 0, _img.Width, _img.Height), GraphicsUnit.Pixel);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
if (_showText)
{
//Region reg = new Region(borderPath);
//reg.Intersect(new RectangleF(0, borderRect.Y, Width, _textHeight));
//g.FillRegion(new SolidBrush(theme.LOST_FOCUS_COLOR), reg);
//文字
g.DrawString(Text, TitleFont, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect);
}
//控件边框
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//图标
if (_img != null)
g.DrawImage(_img, imgRect, new RectangleF(0, 0, _img.Width, _img.Height), GraphicsUnit.Pixel);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
Graphics g = CreateGraphics();
SizeF sf = g.MeasureString(Text, TitleFont);
imgRect = new RectangleF(0, (_textHeight - _imgSize.Height) / 2f, _imgSize.Width, _imgSize.Height);
textRect = new RectangleF(0, (_textHeight - sf.Height) / 2f, sf.Width, sf.Height);
float x;
switch (TextAlign)
{
case HorizontalAlignment.Left:
x = BorderWidth;
if (_img != null)
{
imgRect.X = x;
x += _imgSize.Width + SPACE;
}
textRect.X = x;
break;
case HorizontalAlignment.Center:
if (_img != null)
{
x = (Width - sf.Width - _imgSize.Width - SPACE) / 2f;
imgRect.X = x;
x += _imgSize.Width + SPACE;
}
else
{
x = (Width - sf.Width) / 2f;
}
textRect.X = x;
break;
case HorizontalAlignment.Right:
x = Width - BorderWidth - sf.Width;
textRect.X = x;
if (_img != null)
{
x -= (SPACE + _imgSize.Width);
imgRect.X = x;
}
break;
}
}
private void FaceButton_MouseMove(object sender, MouseEventArgs e)
{
//buttonOver = borderPath.IsVisible(e.Location);
//Refresh();
}
}
}

namespace FaceControl
{
partial class FaceRadio
{
/// <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();
//
// FaceRadio
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceRadio";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceRadio_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceRadio_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceRadio_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace FaceControl
{
partial class FaceRadioGroup
{
/// <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();
//
// FaceRadioGroup
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceRadioGroup";
this.Size = new System.Drawing.Size(85, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceRadioGroup_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceRadioGroup_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceRadioGroup_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
using System;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace FaceControl
{
[DefaultProperty("SelectedIndex")]
[DefaultEvent("CheckedChanged")]
public partial class FaceRadioGroup : ControlBase
{
private int buttonOverIndex = -1;
private int buttonDownIndex = -1;
private RectangleF[] textRect;
private RectangleF[] buttonRect;
private GraphicsPath borderPath = new GraphicsPath();
public FaceRadioGroup()
{
InitializeComponent();
}
#region 事件
[Browsable(true), Category("杂项"), Description("当checked属性更改值时发生")]
public event EventHandler CheckedChanged;
#endregion
#region 属性
[Browsable(false)]
public int SelectedIndex
{
get => buttonDownIndex;
set
{
buttonDownIndex = value;
Refresh();
CheckedChanged?.Invoke(this, new EventArgs());
}
}
[Browsable(false)]
public string SelectedText
{
set
{
string[] s = Text.Split(',');
int idx = Array.FindIndex(s, match => match == value);
if (idx == -1) return;
SelectedIndex = idx;
}
get
{
if (buttonDownIndex == -1) return "";
string[] s = Text.Split(',');
return s[buttonDownIndex];
}
}
#endregion
protected override void CalcSize()
{
base.CalcSize();
CalcTextLocation();
CalcShape();
}
protected override void DrawEnabled(Graphics g)
{
base.DrawEnabled(g);
//控件边框
if (CursorInside && buttonOverIndex > -1)
{
if (buttonDownIndex != -1)
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), buttonRect[buttonDownIndex]);
if (buttonDownIndex != buttonOverIndex)
g.FillRectangle(new SolidBrush(theme.OVER_COLOR), buttonRect[buttonOverIndex]); //经过
Region reg = new Region(new Rectangle(0, 0, Width, Height));
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(theme.BACK_COLOR), reg);
if (BorderWidth > 0)
g.DrawPath(borderInsidePen, borderPath);
}
else
{
buttonOverIndex = -1;
g.FillPath(new SolidBrush(BackColor), borderPath);
if (buttonDownIndex != -1)
g.FillRectangle(new SolidBrush(theme.DOWN_COLOR), buttonRect[buttonDownIndex]);
Region reg = new Region(new Rectangle(0, 0, Width, Height));
reg.Exclude(borderPath);
g.FillRegion(new SolidBrush(theme.BACK_COLOR), reg);
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
}
//文字
string[] s = Text.Split(',');
for (int i = 0; i < s.Length; i++)
g.DrawString(s[i], Font, new SolidBrush(ForeColor), textRect[i]);
}
protected override void DrawDisabled(Graphics g)
{
base.DrawDisabled(g);
//控件边框
if (BorderWidth > 0)
g.DrawPath(borderOutsidePen, borderPath);
//文字
string[] s = Text.Split(',');
for (int i = 0; i < s.Length; i++)
g.DrawString(s[i], Font, new SolidBrush(theme.LOST_FOCUS_COLOR), textRect[i]);
}
private void CalcShape()
{
borderPath = new GraphicsPath();
float n;
switch (FaceShape)
{
case Model.ButtonShape.Rectangle:
borderPath.AddRectangle(borderRect);
break;
case Model.ButtonShape.RoundRectangle:
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);
break;
case Model.ButtonShape.Ellipse:
borderPath.AddEllipse(borderRect);
break;
case Model.ButtonShape.EllipseRectangle:
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);
break;
case Model.ButtonShape.Circle:
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);
break;
}
}
private void CalcTextLocation()
{
if (string.IsNullOrEmpty(Text)) return;
Graphics g = CreateGraphics();
string[] s = Text.Split(',');
buttonRect = new RectangleF[s.Length];
textRect = new RectangleF[s.Length];
float w = (Width - BorderWidth - BorderWidth) / (float)s.Length;
float h = Height - BorderWidth - BorderWidth;
for (int i = 0; i < s.Length; i++)
{
buttonRect[i] = new RectangleF(BorderWidth + w * i, BorderWidth, w, h);
SizeF sf = g.MeasureString(s[i], Font);
textRect[i] = new RectangleF(0, (h - sf.Height) / 2f, sf.Width, sf.Height);
switch (TextAlign)
{
case HorizontalAlignment.Left:
textRect[i].X = buttonRect[i].X;
break;
case HorizontalAlignment.Center:
textRect[i].X = buttonRect[i].X + (buttonRect[i].Width - sf.Width) / 2f;
break;
case HorizontalAlignment.Right:
textRect[i].X = buttonRect[i].X + buttonRect[i].Width - sf.Width;
break;
}
}
}
private void FaceRadioGroup_MouseDown(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
buttonDownIndex = buttonOverIndex;
Refresh();
}
}
private void FaceRadioGroup_MouseUp(object sender, MouseEventArgs e)
{
if (!Enabled) return;
if (e.Button == MouseButtons.Left)
{
Refresh();
CheckedChanged?.Invoke(this, new EventArgs());
}
}
private void FaceRadioGroup_MouseMove(object sender, MouseEventArgs e)
{
buttonOverIndex = -1;
for (int i = 0; i < buttonRect.Length; i++)
{
if (buttonRect[i].Contains(e.Location))
{
buttonOverIndex = i;
break;
}
}
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 \ No newline at end of file

namespace 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.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceScrollBar";
this.Size = new System.Drawing.Size(25, 97);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceButton_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceButton_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceButton_MouseUp);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file

namespace FaceControl
{
partial class FaceText
{
/// <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();
//
// FaceText
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Name = "FaceText";
this.Size = new System.Drawing.Size(130, 45);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.FaceText_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.FaceText_MouseMove);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.FaceText_MouseUp);
this.Resize += new System.EventHandler(this.FaceText_Resize);
this.ResumeLayout(false);
}
#endregion
}
}
<?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 \ No newline at end of file
此文件的差异被折叠, 点击展开。
此文件的差异被折叠, 点击展开。
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
此文件类型无法预览
支持 Markdown 格式
你添加了 0 到此讨论。请谨慎行事。
Finish editing this message first!