UIPieChart:增加Title,Legend,Tip

This commit is contained in:
Sunny 2020-06-07 23:21:42 +08:00
parent cd8db8cdf7
commit 5b43a40600
20 changed files with 604 additions and 60 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -28,11 +28,14 @@
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.uiLine1 = new Sunny.UI.UILine();
this.PieChart = new Sunny.UI.UIPieChart();
this.uiImageButton1 = new Sunny.UI.UIImageButton();
this.uiImageButton2 = new Sunny.UI.UIImageButton();
this.uiImageButton3 = new Sunny.UI.UIImageButton();
this.uiSymbolButton1 = new Sunny.UI.UISymbolButton();
this.toolTip1 = new System.Windows.Forms.ToolTip(this.components);
this.PagePanel.SuspendLayout();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton1)).BeginInit();
((System.ComponentModel.ISupportInitialize)(this.uiImageButton2)).BeginInit();
@ -41,12 +44,13 @@
//
// PagePanel
//
this.PagePanel.Controls.Add(this.uiSymbolButton1);
this.PagePanel.Controls.Add(this.uiImageButton3);
this.PagePanel.Controls.Add(this.uiImageButton2);
this.PagePanel.Controls.Add(this.uiImageButton1);
this.PagePanel.Controls.Add(this.PieChart);
this.PagePanel.Controls.Add(this.uiLine1);
this.PagePanel.Size = new System.Drawing.Size(800, 461);
this.PagePanel.Size = new System.Drawing.Size(828, 517);
//
// uiLine1
//
@ -64,11 +68,11 @@
this.PieChart.FillColor = System.Drawing.Color.FromArgb(((int)(((byte)(244)))), ((int)(((byte)(244)))), ((int)(((byte)(244)))));
this.PieChart.Font = new System.Drawing.Font("微软雅黑", 12F);
this.PieChart.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(54)))), ((int)(((byte)(54)))), ((int)(((byte)(54)))));
this.PieChart.Location = new System.Drawing.Point(26, 59);
this.PieChart.Location = new System.Drawing.Point(26, 46);
this.PieChart.Name = "PieChart";
this.PieChart.Option = null;
this.PieChart.RectSides = System.Windows.Forms.ToolStripStatusLabelBorderSides.None;
this.PieChart.Size = new System.Drawing.Size(566, 358);
this.PieChart.Size = new System.Drawing.Size(687, 399);
this.PieChart.TabIndex = 20;
this.PieChart.Text = "uiPieChart1";
//
@ -76,9 +80,9 @@
//
this.uiImageButton1.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton1.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDefaultStyle;
this.uiImageButton1.Location = new System.Drawing.Point(604, 60);
this.uiImageButton1.Location = new System.Drawing.Point(26, 470);
this.uiImageButton1.Name = "uiImageButton1";
this.uiImageButton1.Size = new System.Drawing.Size(95, 27);
this.uiImageButton1.Size = new System.Drawing.Size(100, 27);
this.uiImageButton1.TabIndex = 21;
this.uiImageButton1.TabStop = false;
this.uiImageButton1.Text = " Default";
@ -89,9 +93,9 @@
//
this.uiImageButton2.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton2.Image = global::Sunny.UI.Demo.Properties.Resources.ChartPlainStyle;
this.uiImageButton2.Location = new System.Drawing.Point(604, 93);
this.uiImageButton2.Location = new System.Drawing.Point(132, 470);
this.uiImageButton2.Name = "uiImageButton2";
this.uiImageButton2.Size = new System.Drawing.Size(95, 27);
this.uiImageButton2.Size = new System.Drawing.Size(100, 27);
this.uiImageButton2.TabIndex = 22;
this.uiImageButton2.TabStop = false;
this.uiImageButton2.Text = " Plain";
@ -102,20 +106,33 @@
//
this.uiImageButton3.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiImageButton3.Image = global::Sunny.UI.Demo.Properties.Resources.ChartDarkStyle;
this.uiImageButton3.Location = new System.Drawing.Point(604, 126);
this.uiImageButton3.Location = new System.Drawing.Point(238, 470);
this.uiImageButton3.Name = "uiImageButton3";
this.uiImageButton3.Size = new System.Drawing.Size(95, 27);
this.uiImageButton3.Size = new System.Drawing.Size(100, 27);
this.uiImageButton3.TabIndex = 23;
this.uiImageButton3.TabStop = false;
this.uiImageButton3.Text = " Dark";
this.uiImageButton3.TextAlign = System.Drawing.ContentAlignment.MiddleLeft;
this.uiImageButton3.Click += new System.EventHandler(this.uiImageButton3_Click);
//
// uiSymbolButton1
//
this.uiSymbolButton1.Cursor = System.Windows.Forms.Cursors.Hand;
this.uiSymbolButton1.Font = new System.Drawing.Font("微软雅黑", 12F);
this.uiSymbolButton1.Location = new System.Drawing.Point(344, 470);
this.uiSymbolButton1.Name = "uiSymbolButton1";
this.uiSymbolButton1.Padding = new System.Windows.Forms.Padding(28, 0, 0, 0);
this.uiSymbolButton1.Size = new System.Drawing.Size(100, 27);
this.uiSymbolButton1.Symbol = 61952;
this.uiSymbolButton1.TabIndex = 24;
this.uiSymbolButton1.Text = "数据";
this.uiSymbolButton1.Click += new System.EventHandler(this.uiSymbolButton1_Click);
//
// FPieChart
//
this.AutoScaleDimensions = new System.Drawing.SizeF(10F, 21F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(800, 496);
this.ClientSize = new System.Drawing.Size(828, 552);
this.Name = "FPieChart";
this.Text = "PieChart";
this.PagePanel.ResumeLayout(false);
@ -132,5 +149,7 @@
private UIImageButton uiImageButton1;
private UIImageButton uiImageButton3;
private UIImageButton uiImageButton2;
private UISymbolButton uiSymbolButton1;
private System.Windows.Forms.ToolTip toolTip1;
}
}

View File

@ -21,5 +21,52 @@
{
PieChart.ChartStyleType = UIChartStyleType.Dark;
}
private void uiSymbolButton1_Click(object sender, System.EventArgs e)
{
var option = new UIOption();
//设置Title
option.Title = new UITitle();
option.Title.Text = "SunnyUI";
option.Title.SubText = "Star";
option.Title.Left = UILeftAlignment.Center;
//设置Legend
option.Legend = new UILegend();
option.Legend.Orient = Orient.Vertical;
option.Legend.Top = UITopAlignment.Top;
option.Legend.Left = UILeftAlignment.Left;
option.Legend.AddData("2020-05-19");
option.Legend.AddData("2020-05-20");
option.Legend.AddData("2020-05-21");
option.Legend.AddData("2020-05-22");
option.Legend.AddData("2020-05-23");
option.Legend.AddData("2020-05-24");
option.Legend.AddData("2020-05-25");
//设置Series
var series = new UISeries();
series.Name = "Star count";
series.Type = UISeriesType.Pie;
series.Center = new UICenter(50, 55);
series.Radius = 70;
//增加数据
series.AddData("2020-05-19", 38);
series.AddData("2020-05-20", 21);
series.AddData("2020-05-21", 11);
series.AddData("2020-05-22", 52);
series.AddData("2020-05-23", 23);
series.AddData("2020-05-24", 26);
series.AddData("2020-05-25", 27);
//增加Series
option.Series.Add(series);
//设置Option
PieChart.SetOption(option);
}
}
}

View File

@ -117,4 +117,7 @@
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<metadata name="toolTip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value>
</metadata>
</root>

View File

@ -48,9 +48,8 @@
this.uiTitlePanel1.Location = new System.Drawing.Point(30, 230);
this.uiTitlePanel1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.uiTitlePanel1.Name = "uiTitlePanel1";
this.uiTitlePanel1.Padding = new System.Windows.Forms.Padding(1, 35, 1, 1);
this.uiTitlePanel1.Padding = new System.Windows.Forms.Padding(0, 35, 0, 0);
this.uiTitlePanel1.Size = new System.Drawing.Size(270, 180);
this.uiTitlePanel1.Style = Sunny.UI.UIStyle.Custom;
this.uiTitlePanel1.TabIndex = 1;
this.uiTitlePanel1.Text = "uiTitlePanel1";
//
@ -70,6 +69,7 @@
this.uiGroupBox1.Location = new System.Drawing.Point(331, 4);
this.uiGroupBox1.Margin = new System.Windows.Forms.Padding(4, 5, 4, 5);
this.uiGroupBox1.Name = "uiGroupBox1";
this.uiGroupBox1.Padding = new System.Windows.Forms.Padding(0, 32, 0, 0);
this.uiGroupBox1.Size = new System.Drawing.Size(270, 196);
this.uiGroupBox1.TabIndex = 4;
this.uiGroupBox1.Text = "uiGroupBox1";

View File

@ -4,7 +4,7 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Sunny.UI.Charts
namespace Sunny.UI
{
public class UIChart : UIControl
{
@ -65,19 +65,24 @@ namespace Sunny.UI.Charts
g.FillPath(fillColor, path);
}
private UIOption option;
private UIOption _option;
[Browsable(false)]
public UIOption Option
{
get => option;
get => _option;
set
{
option = value;
_option = value;
Invalidate();
}
}
public void SetOption(UIOption option)
{
Option = option;
}
protected UIOption emptyOption;
protected UIOption EmptyOption
@ -129,5 +134,34 @@ namespace Sunny.UI.Charts
fillColor = ChartStyle.BackColor;
foreColor = ChartStyle.ForeColor;
}
[DefaultValue(8)]
public int TextInterval { get; set; } = 8;
public Font subFont = UIFontColor.SubFont;
[DefaultValue(typeof(Font), "微软雅黑, 9pt")]
public Font SubFont
{
get => subFont;
set
{
subFont = value;
Invalidate();
}
}
public Font legendFont = UIFontColor.SubFont;
[DefaultValue(typeof(Font), "微软雅黑, 9pt")]
public Font LegendFont
{
get => legendFont;
set
{
legendFont = value;
Invalidate();
}
}
}
}

View File

@ -32,25 +32,53 @@ namespace Sunny.UI
public class UILegend
{
public UILeftAlignment Left { get; set; } = UILeftAlignment.Center;
public UITopAlignment Top { get; set; } = UITopAlignment.Top;
public Orient Orient { get; set; } = Orient.Vertical;
public readonly List<string> Data = new List<string>();
public int DataCount => Data.Count;
public void AddData(string data)
{
Data.Add(data);
}
}
public enum Orient
{
Vertical,
Horizontal
}
public class UITitle
{
public string Text { get; set; }
{
public string Text { get; set; } = "UIPieChart";
public string SubText { get; set; }
public string SubText { get; set; } = "";
public UITextAlignment Left { get; set; }
public UILeftAlignment Left { get; set; } = UILeftAlignment.Center;
public UITopAlignment Top { get; set; } = UITopAlignment.Top;
}
public enum UITextAlignment
public enum UILeftAlignment
{
Left,
Center,
Right
}
public enum UITopAlignment
{
Top,
Center,
Bottom
}
public class UISeries : IDisposable
{
public string Name { get; set; }

View File

@ -1,9 +1,9 @@
using Sunny.UI.Charts;
using System;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
namespace Sunny.UI
@ -11,6 +11,56 @@ namespace Sunny.UI
[ToolboxItem(true)]
public sealed class UIPieChart : UIChart
{
public UIPieChart()
{
tip.Parent = this;
tip.Height = 32;
tip.Width = 200;
tip.Left = 1;
tip.Top = 1;
tip.BackColor = Color.FromArgb(80, Color.Black);
tip.Font = UIFontColor.SubFont;
tip.Style = UIStyle.Custom;
tip.StyleCustomMode = true;
tip.FillColor = Color.Black;
tip.RectColor = Color.FromArgb(100, Color.Black);
tip.Visible = false;
}
private readonly UIAlphaPanel tip = new UIAlphaPanel();
public class UIAlphaPanel : UIPanel
{
private int _opacity = 50;
[Bindable(true), Category("Custom"), DefaultValue(125), Description("背景的透明度. 有效值0-255")]
public int Opacity
{
get { return _opacity; }
set
{
if (value > 255) value = 255;
else if (value < 0) value = 0;
_opacity = value;
this.Invalidate();
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x00000020; //WS_EX_TRANSPARENT
return cp;
}
}
protected override void OnPaintFill(Graphics g, GraphicsPath path)
{
}
}
protected override void CreateEmptyOption()
{
if (emptyOption != null) return;
@ -20,13 +70,12 @@ namespace Sunny.UI
emptyOption.Title = new UITitle();
emptyOption.Title.Text = "SunnyUI";
emptyOption.Title.SubText = "PieChart";
emptyOption.Title.Left = UITextAlignment.Center;
var series = new UISeries();
series.Name = "饼状图";
series.Type = UISeriesType.Pie;
series.Center = new UICenter(50, 50);
series.Radius = 75;
series.Center = new UICenter(50, 55);
series.Radius = 70;
for (int i = 0; i < 5; i++)
{
series.AddData("Data" + i, (i + 1) * 20);
@ -37,6 +86,41 @@ namespace Sunny.UI
protected override void DrawTitle(Graphics g, UITitle title)
{
if (title == null) return;
SizeF sf = g.MeasureString(title.Text, Font);
float left = 0;
switch (title.Left)
{
case UILeftAlignment.Left: left = TextInterval; break;
case UILeftAlignment.Center: left = (Width - sf.Width) / 2.0f; break;
case UILeftAlignment.Right: left = Width - TextInterval - sf.Width; break;
}
float top = 0;
switch (title.Top)
{
case UITopAlignment.Top: top = TextInterval; break;
case UITopAlignment.Center: top = (Height - sf.Height) / 2.0f; break;
case UITopAlignment.Bottom: top = Height - TextInterval - sf.Height; break;
}
g.DrawString(title.Text, Font, ChartStyle.ForeColor, left, top);
SizeF sfs = g.MeasureString(title.SubText, SubFont);
switch (title.Left)
{
case UILeftAlignment.Left: left = TextInterval; break;
case UILeftAlignment.Center: left = (Width - sfs.Width) / 2.0f; break;
case UILeftAlignment.Right: left = Width - TextInterval - sf.Width; break;
}
switch (title.Top)
{
case UITopAlignment.Top: top = top + sf.Height; break;
case UITopAlignment.Center: top = top + sf.Height; break;
case UITopAlignment.Bottom: top = top - sf.Height; break;
}
g.DrawString(title.SubText, subFont, ChartStyle.ForeColor, left, top);
}
protected override void DrawSeries(Graphics g, List<UISeries> series)
@ -63,15 +147,17 @@ namespace Sunny.UI
for (int i = 0; i < pie.Data.Count; i++)
{
float angle = (float)(pie.Data[i].Value * 360.0f / all);
Angles[pieIndex].AddOrUpdate(i, new Angle(start, angle));
string text = pie.Data[i].Name + ": " + pie.Data[i].Value.ToString("F0");
SizeF sf = g.MeasureString(text, legendFont);
Angles[pieIndex].AddOrUpdate(i, new Angle(start, angle, text, sf));
start += angle;
}
for (int i = 0; i < pie.Data.Count; i++)
for (int azIndex = 0; azIndex < pie.Data.Count; azIndex++)
{
Color color = ChartStyle.SeriesColor[i % ChartStyle.ColorCount];
Color color = ChartStyle.SeriesColor[azIndex % ChartStyle.ColorCount];
RectangleF rectx = new RectangleF(rect.X - 10, rect.Y - 10, rect.Width + 20, rect.Width + 20);
g.FillPie(color, ActiveIndex == i ? rectx : rect, Angles[pieIndex][i].Start - 90, Angles[pieIndex][i].Sweep);
g.FillPie(color, (ActivePieIndex == pieIndex && ActiveAzIndex == azIndex) ? rectx : rect, Angles[pieIndex][azIndex].Start - 90, Angles[pieIndex][azIndex].Sweep);
}
}
}
@ -80,6 +166,70 @@ namespace Sunny.UI
protected override void DrawLegend(Graphics g, UILegend legend)
{
if (legend == null) return;
float totalHeight = 0;
float totalWidth = 0;
float maxWidth = 0;
float oneHeight = 0;
foreach (var data in legend.Data)
{
SizeF sf = g.MeasureString(data, LegendFont);
totalHeight += sf.Height;
totalWidth += sf.Width;
totalWidth += 20;
maxWidth = Math.Max(sf.Width, maxWidth);
oneHeight = sf.Height;
}
float top = 0;
float left = 0;
if (legend.Orient == Orient.Horizontal)
{
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
if (legend.Left == UILeftAlignment.Center) left = (Width - totalWidth) / 2.0f;
if (legend.Left == UILeftAlignment.Right) left = Width - totalWidth - TextInterval;
if (legend.Top == UITopAlignment.Top) top = TextInterval;
if (legend.Top == UITopAlignment.Center) top = (Height - oneHeight) / 2.0f;
if (legend.Top == UITopAlignment.Bottom) top = Height - oneHeight - TextInterval;
}
if (legend.Orient == Orient.Vertical)
{
if (legend.Left == UILeftAlignment.Left) left = TextInterval;
if (legend.Left == UILeftAlignment.Center) left = (Width - maxWidth) / 2.0f - 10;
if (legend.Left == UILeftAlignment.Right) left = Width - maxWidth - TextInterval - 20;
if (legend.Top == UITopAlignment.Top) top = TextInterval;
if (legend.Top == UITopAlignment.Center) top = (Height - totalHeight) / 2.0f;
if (legend.Top == UITopAlignment.Bottom) top = Height - totalHeight - TextInterval;
}
float startleft = left;
float starttop = top;
for (int i = 0; i < legend.DataCount; i++)
{
var data = legend.Data[i];
SizeF sf = g.MeasureString(data, LegendFont);
if (legend.Orient == Orient.Horizontal)
{
g.FillRoundRectangle(ChartStyle.SeriesColor[i % ChartStyle.ColorCount], (int)startleft, (int)top + 1, 18, (int)oneHeight - 2, 5);
g.DrawString(data, LegendFont, ChartStyle.ForeColor, startleft + 20, top);
startleft += 20;
startleft += sf.Width;
}
if (legend.Orient == Orient.Vertical)
{
g.FillRoundRectangle(ChartStyle.SeriesColor[i % ChartStyle.ColorCount], (int)left, (int)starttop + 1, 18, (int)oneHeight - 2, 5);
g.DrawString(data, LegendFont, ChartStyle.ForeColor, left + 20, starttop);
starttop += oneHeight;
}
}
}
protected override void OnMouseMove(MouseEventArgs e)
@ -87,47 +237,50 @@ namespace Sunny.UI
base.OnMouseMove(e);
UIOption option = Option ?? EmptyOption;
int index = -1;
if (option.SeriesCount == 0)
{
SetPieAndAzIndex(-1, -1);
return;
}
for (int pieIndex = 0; pieIndex < option.SeriesCount; pieIndex++)
{
RectangleF rect = GetSeriesRect(option.Series[pieIndex]);
if (!e.Location.InRect(rect)) continue;
PointF pf = new PointF( rect.Left +rect.Width/2.0f,rect.Top +rect.Height/2.0f);
PointF pf = new PointF(rect.Left + rect.Width / 2.0f, rect.Top + rect.Height / 2.0f);
if (MathEx.CalcDistance(e.Location, pf) * 2 > rect.Width) continue;
double az =MathEx.CalcAngle(e.Location,pf);
double az = MathEx.CalcAngle(e.Location, pf);
for (int azIndex = 0; azIndex < option.Series[pieIndex].Data.Count; azIndex++)
{
if (az >= Angles[pieIndex][azIndex].Start && az <= Angles[pieIndex][azIndex].Start + Angles[pieIndex][azIndex].Sweep)
{
index = azIndex;
break;
SetPieAndAzIndex(pieIndex, azIndex);
tip.Size = new Size((int)Angles[pieIndex][azIndex].Size.Width + 4, (int)Angles[pieIndex][azIndex].Size.Height + 4);
tip.Text = Angles[pieIndex][azIndex].Text;
tip.Left = e.Location.X + 15;
tip.Top = e.Location.Y + 20;
tip.Visible = true;
return;
}
}
}
ActiveIndex = index;
SetPieAndAzIndex(-1, -1);
tip.Visible = false;
}
public double Rad(double d)
{
return d * Math.PI / 180.0;
}
private int ActiveAzIndex = -1;
private int ActivePieIndex = -1;
private int activeIndex = -1;
[Browsable(false)]
private int ActiveIndex
private void SetPieAndAzIndex(int pieIndex, int azIndex)
{
get => activeIndex;
set
if (ActivePieIndex != pieIndex || ActiveAzIndex != azIndex)
{
if (activeIndex != value)
{
activeIndex = value;
Invalidate();
}
ActivePieIndex = pieIndex;
ActiveAzIndex = azIndex;
Invalidate();
}
}
@ -146,11 +299,17 @@ namespace Sunny.UI
public float Start { get; set; }
public float Sweep { get; set; }
public Angle(float start, float sweep)
public Angle(float start, float sweep, string text, SizeF size)
{
Start = start;
Sweep = sweep;
Text = text;
Size = size;
}
public SizeF Size { get; set; }
public string Text { get; set; }
}
}
}

View File

@ -28,12 +28,13 @@
/// </summary>
private void InitializeComponent()
{
SuspendLayout();
this.SuspendLayout();
//
// UIGroupBox
//
Name = "UIGroupBox";
ResumeLayout(false);
this.Name = "UIGroupBox";
this.Padding = new System.Windows.Forms.Padding(0, 32, 0, 0);
this.ResumeLayout(false);
}

View File

@ -79,6 +79,7 @@ namespace Sunny.UI
if (_titleTop != value)
{
_titleTop = value;
Padding = new Padding(0, value+16, 0, 0);
Invalidate();
}
}

View File

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

View File

@ -28,13 +28,13 @@
/// </summary>
private void InitializeComponent()
{
SuspendLayout();
this.SuspendLayout();
//
// UITitlePanel
//
Name = "UITitlePanel";
Padding = new System.Windows.Forms.Padding(1, 35, 1, 1);
ResumeLayout(false);
this.Name = "UITitlePanel";
this.Padding = new System.Windows.Forms.Padding(0, 35, 0, 0);
this.ResumeLayout(false);
}

View File

@ -39,7 +39,7 @@ namespace Sunny.UI
set
{
_titleHeight = value;
Padding = new Padding(1, value, 1, 1);
Padding = new Padding(0, value, 0, 0);
Invalidate();
}
}

View File

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

View File

@ -580,6 +580,11 @@ namespace Sunny.UI
/// </summary>
public static readonly Font Font = new Font("微软雅黑", 12);
/// <summary>
/// 默认字体
/// </summary>
public static readonly Font SubFont = new Font("微软雅黑", 9);
/// <summary>
/// 主要颜色
/// </summary>

View File

@ -480,9 +480,15 @@
<EmbeddedResource Include="Controls\UIDatetimePicker.resx">
<DependentUpon>UIDatetimePicker.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\UIGroupBox.resx">
<DependentUpon>UIGroupBox.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\UITimePicker.resx">
<DependentUpon>UITimePicker.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Controls\UITitlePanel.resx">
<DependentUpon>UITitlePanel.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="Forms\UINotifier.resx">
<DependentUpon>UINotifier.cs</DependentUpon>
</EmbeddedResource>

View File

@ -2,6 +2,7 @@
2020.06.07
* UITabControl重绘了页面左右控制按钮
* UIPieChart增加TitleLegendTip
2020.06.06
+ UIPieChart新增