功能调整

This commit is contained in:
wule committed 2026-06-12 11:37:01 +08:00
1 parent 42acf1b1cb
commit 772d9f4780
40 files changed
+4953 -389

No files matched your search

+27
View File
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Work.UserComponents
{
class ButtonLc:Button
{
///不显示控件获焦提示
protected override bool ShowFocusCues
{
get { return false; }
}
}
class LinkLabelLc : LinkLabel
{
///不显示控件获焦提示
protected override bool ShowFocusCues
{
get { return false; }
}
}
}
@@ -0,0 +1,203 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
namespace Work.UserComponents
{
/// <summary>
/// 带表头全选的选择框列
/// </summary>
public class DataGridViewCheckBoxColumnSelectAll : DataGridViewCheckBoxColumn
{
private DatagridViewCheckBoxHeaderCell headerCell;
private bool loaded;
public event CheckBoxClickedHandler OnCheckBoxClicked;
int TotalCheckedCheckBoxes = 0;
bool IsHeaderCheckBoxClicked = false;
public DataGridViewCheckBoxColumnSelectAll()
{
this.headerCell = new DatagridViewCheckBoxHeaderCell();
base.HeaderCell = this.headerCell;
this.headerCell.OnCheckBoxClicked += new CheckBoxClickedHandler(this.headerCell_OnCheckBoxClicked);
this.loaded = false;
}
public DataGridViewCheckBoxColumnSelectAll(bool threeState)
: base(threeState)
{
this.headerCell = new DatagridViewCheckBoxHeaderCell();
base.HeaderCell = this.headerCell;
}
/// <summary>
/// 在DataGridView改变时进行事件的绑定
/// </summary>
protected override void OnDataGridViewChanged()
{
if (this.DataGridView != null)
{
this.DataGridView.CellValueChanged -= DataGridView_CellValueChanged;
this.DataGridView.CellValueChanged += DataGridView_CellValueChanged;
this.DataGridView.CurrentCellDirtyStateChanged -= DataGridView_CurrentCellDirtyStateChanged;
this.DataGridView.CurrentCellDirtyStateChanged += DataGridView_CurrentCellDirtyStateChanged;
}
}
/// <summary>
/// 在复选的时候进行判断.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
void DataGridView_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
if (e.RowIndex >= 0 && e.ColumnIndex >= 0)
{
if (!IsHeaderCheckBoxClicked)
RowCheckBoxClick((DataGridViewCheckBoxCell)this.DataGridView[e.ColumnIndex, e.RowIndex]);
}
}
/// <summary>
/// 在复选框被选中的时候触发该事件, 该事件用于触发ValueChanged事件
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataGridView_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (this.DataGridView.CurrentCell is DataGridViewCheckBoxCell)
this.DataGridView.CommitEdit(DataGridViewDataErrorContexts.Commit);
}
/// <summary>
/// 复选框被点击时所需要做的操作
/// </summary>
/// <param name="checkBox"></param>
private void RowCheckBoxClick(DataGridViewCheckBoxCell checkBox)
{
var head = this.headerCell as DatagridViewCheckBoxHeaderCell;
if (checkBox != null)
{
//计算所有被选中的行的数量
if ((bool)checkBox.Value && TotalCheckedCheckBoxes < this.DataGridView.RowCount)
TotalCheckedCheckBoxes++;
else if (TotalCheckedCheckBoxes > 0)
TotalCheckedCheckBoxes--;
//当所有复选框都被选中的时候,列的头上的复选框被选中, 反之则不被选中.
if (TotalCheckedCheckBoxes < this.DataGridView.RowCount)
head.IsChecked = false;
else if (TotalCheckedCheckBoxes == this.DataGridView.RowCount)
head.IsChecked = true;
//强制repained
head.DataGridView.InvalidateCell(head);
}
}
/// <summary>
/// 头被选中时触发OnCheckBoxClicked事件.
/// </summary>
/// <param name="state"></param>
private void headerCell_OnCheckBoxClicked(bool state)
{
if (this.OnCheckBoxClicked != null)
{
this.OnCheckBoxClicked(state);
}
}
public delegate void CheckBoxClickedHandler(bool state);
internal class DatagridViewCheckBoxHeaderCell : DataGridViewColumnHeaderCell
{
private CheckBoxState _cbState = CheckBoxState.UncheckedNormal;
private Point _cellLocation = new Point();
private bool _checked;
private Point checkBoxLocation;
private Size checkBoxSize;
public bool IsChecked
{
get
{
return _checked;
}
set
{
_checked = value;
if (this._checked)
{
this._cbState = CheckBoxState.CheckedNormal;
}
else
{
this._cbState = CheckBoxState.UncheckedNormal;
}
}
}
public event CheckBoxClickedHandler OnCheckBoxClicked;
/// <summary>
/// 点击列头的时候触发的事件,这里有个判断, 如果点击的位置是复选框则触发OnCheckBoxClicked事件.
/// </summary>
/// <param name="e"></param>
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
Point point = new Point(e.X + this._cellLocation.X, e.Y + this._cellLocation.Y);
if (((point.X >= this.checkBoxLocation.X) && (point.X <= (this.checkBoxLocation.X + this.checkBoxSize.Width))) && ((point.Y >= this.checkBoxLocation.Y) && (point.Y <= (this.checkBoxLocation.Y + this.checkBoxSize.Height))))
{
this._checked = !this._checked;
bool temp = this._checked;
if (this.OnCheckBoxClicked != null)
{
this.OnCheckBoxClicked(this._checked);
base.DataGridView.InvalidateCell(this);
}
foreach (DataGridViewRow row in base.DataGridView.Rows)
{
((DataGridViewCheckBoxCell)row.Cells[e.ColumnIndex]).Value = temp;
}
base.DataGridView.RefreshEdit();
}
base.OnMouseClick(e);
}
/// <summary>
/// 绘制一个CheckBox
/// </summary>
protected override void Paint(Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates dataGridViewElementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
{
base.Paint(graphics, clipBounds, cellBounds, rowIndex, dataGridViewElementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
Point point = new Point();
Size glyphSize = CheckBoxRenderer.GetGlyphSize(graphics, CheckBoxState.UncheckedNormal);
point.X = (cellBounds.Location.X + (cellBounds.Width / 2)) - (glyphSize.Width / 2) - 1; // x位置补偿一个像素(否则在win11中偏右)
point.Y = (cellBounds.Location.Y + (cellBounds.Height / 2)) - (glyphSize.Height / 2);
//point.X = cellBounds.Location.X + (cellBounds.Width - glyphSize.Width) / 2; // 放一块以后除以2会有抖动
//point.Y = cellBounds.Location.Y + (cellBounds.Height - glyphSize.Height) / 2;
this._cellLocation = cellBounds.Location;
this.checkBoxLocation = point;
this.checkBoxSize = glyphSize;
if (this._checked)
{
this._cbState = CheckBoxState.CheckedNormal;
}
else
{
this._cbState = CheckBoxState.UncheckedNormal;
}
CheckBoxRenderer.DrawCheckBox(graphics, this.checkBoxLocation, this._cbState);
}
}
}
}
@@ -0,0 +1,258 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevComponents.DotNetBar.Controls;
using NaiBa.Util.Extension;
namespace Work.UserComponents
{
public class DataGridViewEx : DataGridView
{
Form parentForm = null;
public DataGridViewEx()
{
BackgroundColor = Color.White;
AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(249, 249, 249);
RowPostPaint += DataGridViewEx_RowPostPaint;
this.CellContentClick += DataGridViewEx_CellContentClick;
this.SetStyle(
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.EnableNotifyMessage |
ControlStyles.ResizeRedraw |
ControlStyles.AllPaintingInWmPaint,
true);
this.CellPainting += DataGridViewEx_CellPainting;
Task.Run(() =>
{
for (int i = 0; i < 50; i++)
{
System.Threading.Thread.Sleep(100);
parentForm = FindForm();
if (parentForm != null)
{
parentForm.KeyPreview = true;
parentForm.KeyDown += ParentForm_KeyDown;
parentForm.KeyUp += ParentForm_KeyUp;
break;
}
}
});
}
private void DataGridViewEx_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
if (e.ColumnIndex < 0)
return;
var chkCol = this.Columns.Cast<DataGridViewColumn>().FirstOrDefault(c => c is DataGridViewCheckBoxColumn);
if (chkCol == null)
return;
var colIndex = chkCol.Index;
if (colIndex < 0 || e.ColumnIndex != colIndex)
return;
rowIndex1 = rowIndex2;
rowIndex2 = e.RowIndex;
if (IsShiftDown && MultiSelectCheckBox)
{
if (rowIndex1 > -1 && rowIndex2 > -1)
{
try
{
if (rowIndex1 > rowIndex2)
{
for (int i = rowIndex2; i <= rowIndex1 - 1; i++)
{
this.Rows[i].Cells[colIndex].Value = this.Rows[rowIndex1].Cells[colIndex].Value;
}
if (this.Rows[rowIndex2].Cells[colIndex].Value == this.Rows[rowIndex1].Cells[colIndex].Value && rowIndex1 != rowIndex2)
this.Rows[rowIndex2].Cells[colIndex].Value = !this.Rows[rowIndex2].Cells[colIndex].Value.ParseToBool();
}
else
{
for (int i = rowIndex1; i <= rowIndex2 - 1; i++)
{
this.Rows[i].Cells[colIndex].Value = this.Rows[rowIndex1].Cells[colIndex].Value;
}
if (this.Rows[rowIndex2].Cells[colIndex].Value == this.Rows[rowIndex1].Cells[colIndex].Value && rowIndex1 != rowIndex2)
this.Rows[rowIndex2].Cells[colIndex].Value = !this.Rows[rowIndex2].Cells[colIndex].Value.ParseToBool();
}
//this.ClearSelection();
//this.SetSelectedCellCore(colIndex, rowIndex2, true);
}
catch
{
}
//rowIndex1 = -1;
//rowIndex2 = -1;
}
}
}
int rowIndex1 = -1;
int rowIndex2 = -1;
bool IsShiftDown = false;
private void ParentForm_KeyDown(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Shift:
case Keys.ShiftKey:
case Keys.LShiftKey:
case Keys.RShiftKey:
IsShiftDown = true;
break;
}
}
private void ParentForm_KeyUp(object sender, KeyEventArgs e)
{
switch (e.KeyCode)
{
case Keys.Shift:
case Keys.ShiftKey:
case Keys.LShiftKey:
case Keys.RShiftKey:
IsShiftDown = false;
rowIndex1 = -1;
rowIndex2 = -1;
break;
}
}
private Color _BorderColor = Color.FromArgb(63, 126, 255);
/// <summary>
/// 边框颜色
/// </summary>
[Description("边框颜色"), Category("UserProperty")]
public Color BorderColor
{
get
{
return _BorderColor;
}
set
{
if (_BorderColor != value)
{
_BorderColor = value;
this.Invalidate();
}
}
}
private bool autoRowNumber = true;
/// <summary>
/// 边框颜色
/// </summary>
[Description("自动行号"), Category("UserProperty")]
public bool AutoRowNumber
{
get
{
return autoRowNumber;
}
set
{
if (autoRowNumber != value)
{
autoRowNumber = value;
this.Invalidate();
}
}
}
/// <summary>
/// 自动生成行号
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void DataGridViewEx_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
if (AutoRowNumber)
{
Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, RowHeadersWidth - 4, e.RowBounds.Height);
TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), RowHeadersDefaultCellStyle.Font, rectangle, Color.DarkGray, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
}
}
/// <summary>
/// 绘制边框颜色
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
e.Graphics.DrawRectangle(new Pen(this.BackgroundColor), new Rectangle(1, 1, this.Width - 2, this.Height - 2));
e.Graphics.DrawRectangle(new Pen(this.BorderColor), new Rectangle(0, 0, this.Width - 1, this.Height - 1));
}
private void dataGridView1_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
//if (e.ColumnIndex == yourCheckBoxColumnIndex && e.RowIndex >= 0)
//{
// bool isChecked = (bool)dataGridView1.Rows[e.RowIndex].Cells[e.ColumnIndex].Value;
// Rectangle checkBoxBounds = new Rectangle(e.CellBounds.Location.X + 10, e.CellBounds.Location.Y + (e.CellBounds.Height - 20) / 2, 20, 20); // 自定义大小和位置
// ControlPaint.DrawCheckBox(e.Graphics, checkBoxBounds, DataGridViewState.Default, isChecked); // 绘制复选框
// e.Handled = true; // 阻止默认绘制
//}
}
private int checkBoxSize = 12;
public Color CheckBoxColor = Color.White;
public Color CheckBoxRowBoxCheckColor = Color.Blue;
public Color CheckBoxRowBoxBorderColor = Color.Blue;
private void DataGridViewEx_CellPainting(object sender, DataGridViewCellPaintingEventArgs e)
{
if (e.ColumnIndex >= 0 && e.RowIndex >= 0)
{
var cellTmp = this.Rows[e.RowIndex].Cells[e.ColumnIndex];
if (cellTmp is DataGridViewCheckBoxCell)
{
e.PaintBackground(e.CellBounds, true);
bool isChecked = (bool)cellTmp.Value;
var locationX = e.CellBounds.Location.X + e.CellBounds.Width / 2 - checkBoxSize / 2 - 1;
var locationY = e.CellBounds.Location.Y + e.CellBounds.Height / 2 - checkBoxSize / 2;
Rectangle checkBoxBounds = new Rectangle(locationX, locationY, checkBoxSize, checkBoxSize); // 自定义大小和位置
//ControlPaint.DrawCheckBox(e.Graphics, checkBoxBounds, isChecked ? ButtonState.Checked : ButtonState.Normal); // 绘制复选框
UcCheckBox.DrawCheckBoxIcon(e.Graphics, checkBoxBounds, isChecked, CheckBoxColor, CheckBoxRowBoxCheckColor, CheckBoxRowBoxBorderColor);
e.Handled = true; // 阻止默认绘制
}
}
}
private bool multiSelectCheckBox = true;
/// <summary>
/// 选择框批量选中(使用Shift按键)
/// </summary>
[Description("选择框批量选中(Shift)"), Category("UserProperty")]
public bool MultiSelectCheckBox
{
get
{
return multiSelectCheckBox;
}
set
{
if (multiSelectCheckBox != value)
{
multiSelectCheckBox = value;
this.Invalidate();
}
}
}
}
}
@@ -0,0 +1,123 @@
<?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>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<value>False</value>
</metadata>
</root>
@@ -0,0 +1,27 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using DevComponents.DotNetBar.Controls;
namespace Work.UserComponents
{
public class DataGridViewXEx : DataGridViewX
{
public DataGridViewXEx()
{
BackgroundColor = Color.White;
AlternatingRowsDefaultCellStyle.BackColor = Color.FromArgb(249, 249, 249);
RowPostPaint += DataGridViewXEx_RowPostPaint;
}
private void DataGridViewXEx_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
{
Rectangle rectangle = new Rectangle(e.RowBounds.Location.X, e.RowBounds.Location.Y, RowHeadersWidth - 4, e.RowBounds.Height);
TextRenderer.DrawText(e.Graphics, (e.RowIndex + 1).ToString(), RowHeadersDefaultCellStyle.Font, rectangle, Color.DarkGray, TextFormatFlags.VerticalCenter | TextFormatFlags.Right);
}
}
}
+165
View File
@@ -0,0 +1,165 @@
using AllBase.Helper;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Work.UserComponents
{
public partial class UcCheckBox : CheckBox
{
public UcCheckBox()
{
InitializeComponent();
this.CheckBoxCheckColor = GlobalConfig.MainColor;
this.CheckBoxBorderColor = GlobalConfig.BorderColor;
}
public UcCheckBox(IContainer container)
{
container.Add(this);
this.CheckBoxCheckColor = GlobalConfig.MainColor;
this.CheckBoxBorderColor = GlobalConfig.BorderColor;
InitializeComponent();
}
private int checkBoxSize = 12;
public Color CheckBoxColor = Color.White;
public Color CheckBoxCheckColor = GlobalConfig.DefaultMainColor;
public Color CheckBoxBorderColor = GlobalConfig.DefaultBorderColor;
protected override void OnPaint(PaintEventArgs e)
{
//base.OnPaint(e); // 禁用系统绘制全部
base.OnPaintBackground(e); // 使用系统绘制背景
//if (e.ClipRectangle.X != 0 || e.ClipRectangle.Y != 0)
// return;
Graphics g = e.Graphics;
//g.Clear(this.CheckBoxColor);
//填充背景色
//g.FillRectangle(new SolidBrush(this.BackColor), e.ClipRectangle);
g.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);
Size size = TextRenderer.MeasureText(this.Text, Font);
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // 或者 AntiAliasGridFit // 平滑字体
//e.Graphics.DrawString(this.Text, Font, new SolidBrush(this.ForeColor),
// new PointF(e.ClipRectangle.X + checkBoxSize + 2 + Padding.Left, e.ClipRectangle.Y + (Height - size.Height) / 2));
e.Graphics.DrawString(this.Text, Font, new SolidBrush(this.ForeColor),
new PointF(this.ClientRectangle.X + checkBoxSize + 2 + Padding.Left, this.ClientRectangle.Y + (Height - size.Height) / 2));
Rectangle rt = new Rectangle();
rt.X = 0;
rt.Y = (Height - checkBoxSize) / 2;
rt.Width = checkBoxSize;
rt.Height = checkBoxSize;
if (this.Enabled == false)
DrawCheckBoxIcon(g, rt, this.Checked, Color.LightGray, Color.DarkGray, Color.Gray);
else
DrawCheckBoxIcon(g, rt, this.Checked, this.CheckBoxColor, this.CheckBoxCheckColor, this.CheckBoxBorderColor);
}
public static void DrawCheckBoxIcon(Graphics g, Rectangle rt, bool isChecked, Color checkBoxColor, Color checkBoxCheckColor, Color checkBoxBorderColor)
{
//绘制圆形(注释此句,以备后用)
//Brush brush = new SolidBrush(this.Checked ? checkBoxCheckColor : checkBoxColor);
//g.FillEllipse(brush, 0, (Height - checkBoxSize) / 2, checkBoxSize, checkBoxSize); // 绘制圆形按钮
Color color = isChecked ? checkBoxCheckColor : checkBoxColor;
if (isChecked)
{
DrawRoundedRectangle(g, rt, 2, color, true);
DrawRoundedRectangle(g, rt, 2, checkBoxBorderColor);
// 绘制勾号
Pen p = new Pen(Color.FromArgb(220, 255, 255, 255), 1);
//g.DrawLine(Pens.SkyBlue, rt.X + 3, rt.Y + 6, rt.X + 5, rt.Y + 8);
//g.DrawLine(Pens.SkyBlue, rt.X + 5, rt.Y + 8, rt.X + 9, rt.Y + 4);
g.DrawLine(p, rt.X + 3, rt.Y + 5, rt.X + 5, rt.Y + 7);
g.DrawLine(p, rt.X + 5, rt.Y + 7, rt.X + 9, rt.Y + 3);
g.DrawLine(p, rt.X + 3, rt.Y + 6, rt.X + 5, rt.Y + 8);
g.DrawLine(p, rt.X + 5, rt.Y + 8, rt.X + 9, rt.Y + 4);
g.DrawLine(p, rt.X + 3, rt.Y + 7, rt.X + 5, rt.Y + 9);
g.DrawLine(p, rt.X + 5, rt.Y + 9, rt.X + 9, rt.Y + 5);
}
else
{
DrawRoundedRectangle(g, rt, 3, color, true);
DrawRoundedRectangle(g, rt, 3, checkBoxBorderColor);
}
}
public static void DrawRoundedRectangle(Graphics g, Rectangle rect, int radius, Color color, bool isFill = false)
{
using (GraphicsPath path = new GraphicsPath())
{
path.StartFigure();
path.AddArc(rect.X, rect.Y, radius * 2, radius * 2, 180, 90); // Upper left corner
path.AddArc(rect.Right - radius * 2, rect.Y, radius * 2, radius * 2, 270, 90); // Upper right corner
path.AddArc(rect.Right - radius * 2, rect.Bottom - radius * 2, radius * 2, radius * 2, 0, 90); // Lower right corner
path.AddArc(rect.X, rect.Bottom - radius * 2, radius * 2, radius * 2, 90, 90); // Lower left corner
path.CloseFigure();
//g.FillPath(Brushes.LightBlue, path);
if (isFill)
g.FillPath(new SolidBrush(color), path); // Fill the rounded rectangle
else
g.DrawPath(new Pen(color), path);
}
}
/*
protected override void OnDrawItem(DrawItemEventArgs e)
{
//int ItemsCount = Items.Count;
//Rectangle rect = new Rectangle(0, 0, e.Bounds.Width, e.Bounds.Height * ItemsCount);
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
//// 绘制下拉框背景
//e.Graphics.FillRectangle(new SolidBrush(_BoxCenterColor), rect);
//// 绘制下拉框边框
//e.Graphics.DrawRectangle(new Pen(new SolidBrush(_BorderColor)), rect);
//// 绘制选中文字背景
//for (int i = 0; i < Items.Count; i++)
//{
// if (SelectedItem != null)
// {
// if (SelectedItem.ToString() == Items[i].ToString())
// {
// Rectangle rectSel = new Rectangle(1, e.Bounds.Height * (SelectedIndex), e.Bounds.Width - 2, e.Bounds.Height - 2);
// e.Graphics.FillRectangle(new SolidBrush(Color.White), rectSel);
// }
// }
// // 绘制文字
// e.Graphics.DrawString(Items[i].ToString(), Font, new SolidBrush(_FontColor), new PointF(0, i * (e.Bounds.Height == 0 ? 16 : e.Bounds.Height)));
//}
if (e.Index >= 0)
{
e.Graphics.FillRectangle(new SolidBrush(_BoxCenterColor), e.Bounds);
if ((e.State & DrawItemState.Focus) == DrawItemState.Focus || (e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
// 设置鼠标悬浮ComboBox的item的背景色
e.Graphics.FillRectangle(Brushes.White, e.Bounds);
}
else if (((e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit))
{
// 默认背景
e.Graphics.FillRectangle(new SolidBrush(e.BackColor), e.Bounds);
}
// 绘制文字
e.Graphics.DrawString(Items[e.Index].ToString(), Font, new SolidBrush(_FontColor), new PointF(e.Bounds.X, e.Bounds.Y));
}
}*/
}
}
+37
View File
@@ -0,0 +1,37 @@
namespace Work.UserComponents
{
partial class UcCheckBox
{
/// <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
}
}
@@ -0,0 +1,231 @@
using DevComponents.DotNetBar.Controls;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Work.UserComponents
{
/// <summary>
/// 自定义combobox控件
/// 增加边框,
/// </summary>
#region 需要注意的地方
//DrawMode=OwnerDrawVariale
//DropDownStyle=DropDownList
#endregion
class UcComboBoxBase : ComboBoxEx
{
#region 自定义属性
private Color _BorderColor = Color.FromArgb(87, 100, 108);
private Color _BoxCenterColor = Color.FromArgb(232, 233, 237);
private Color _BoxBackColor = Color.FromArgb(212, 213, 217);
private ButtonBorderStyle _BorderStyle = ButtonBorderStyle.Solid;
private int _ArrowWidth = 2;
private Color _ArrowColor = Color.FromArgb(87, 100, 108);
private bool _ArrowFlag = true;
private Color _FontColor = Color.FromArgb(0, 0, 0);
[Description("边框颜色"), Category("Set")]
public Color BorderColor
{
set { this._BorderColor = value; }
get { return _BorderColor; }
}
[Description("框外颜色"), Category("Set")]
public Color BoxBackColor
{
set { this._BoxBackColor = value; }
get { return this._BoxBackColor; }
}
[Description("框内颜色"), Category("Set")]
public Color BoxCenterColor
{
set { this._BoxCenterColor = value; this.BackColor = value; }
get { return this._BoxCenterColor; }
}
[Description("边框样式"), Category("Set")]
public ButtonBorderStyle BoxBorderStyle
{
set { this._BorderStyle = value; }
get { return this._BorderStyle; }
}
[Description("下拉箭头宽度"), Category("Set")]
public int ArrowWidth
{
set { this._ArrowWidth = value; }
get { return this._ArrowWidth; }
}
[Description("下拉箭头颜色"), Category("Set")]
public Color ArrowColor
{
set { this._ArrowColor = value; }
get { return this._ArrowColor; }
}
[Description("是否绘制下拉箭头"), Category("Set")]
public bool ArrowEnabled
{
set { this._ArrowFlag = value; }
get { return this._ArrowFlag; }
}
[Description("字体颜色"), Category("UserSet")]
public Color FontColor
{
set { this._FontColor = value; }
get { return this._FontColor; }
}
#endregion
public UcComboBoxBase()
{
this.UseCustomBackColor = true;
// 开启双缓冲等
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.EnableNotifyMessage | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
this.DrawMode = DrawMode.OwnerDrawFixed;
this.UpdateStyles();
}
//导入API函数
[System.Runtime.InteropServices.DllImport("user32.dll ")]
static extern IntPtr GetWindowDC(IntPtr hWnd); // 返回hWnd参数所指定的窗口的设备环境。
[System.Runtime.InteropServices.DllImport("user32.dll ")]
static extern int ReleaseDC(IntPtr hWnd, IntPtr hDC); // 函数释放设备上下文环境(DC)
protected override void OnDrawItem(DrawItemEventArgs e)
{
//int ItemsCount = Items.Count;
//Rectangle rect = new Rectangle(0, 0, e.Bounds.Width, e.Bounds.Height * ItemsCount);
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
//// 绘制下拉框背景
//e.Graphics.FillRectangle(new SolidBrush(_BoxCenterColor), rect);
//// 绘制下拉框边框
//e.Graphics.DrawRectangle(new Pen(new SolidBrush(_BorderColor)), rect);
//// 绘制选中文字背景
//for (int i = 0; i < Items.Count; i++)
//{
// if (SelectedItem != null)
// {
// if (SelectedItem.ToString() == Items[i].ToString())
// {
// Rectangle rectSel = new Rectangle(1, e.Bounds.Height * (SelectedIndex), e.Bounds.Width - 2, e.Bounds.Height - 2);
// e.Graphics.FillRectangle(new SolidBrush(Color.White), rectSel);
// }
// }
// // 绘制文字
// e.Graphics.DrawString(Items[i].ToString(), Font, new SolidBrush(_FontColor), new PointF(0, i * (e.Bounds.Height == 0 ? 16 : e.Bounds.Height)));
//}
if (e.Index >= 0)
{
e.Graphics.FillRectangle(new SolidBrush(_BoxCenterColor), e.Bounds);
if ((e.State & DrawItemState.Focus) == DrawItemState.Focus || (e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
// 设置鼠标悬浮ComboBox的item的背景色
e.Graphics.FillRectangle(Brushes.White, e.Bounds);
}
else if (((e.State & DrawItemState.ComboBoxEdit) != DrawItemState.ComboBoxEdit))
{
// 默认背景
e.Graphics.FillRectangle(new SolidBrush(e.BackColor), e.Bounds);
}
// 绘制文字
e.Graphics.DrawString(Items[e.Index].ToString(), Font, new SolidBrush(_FontColor), new PointF(e.Bounds.X, e.Bounds.Y));
}
}
protected override void WndProc(ref Message m)
{
try
{
// WM_PAINT = 0xf; 要求一个窗口重画自己,即Paint事件时
// WM_CTLCOLOREDIT = 0x133; 当一个编辑型控件将要被绘制时发送此消息给它的父窗口;
// 通过响应这条消息,所有者窗口可以通过使用给定的相关显示设备的句柄来设置编辑框的文本和背景颜色
// windows消息值表,可参考:http://hi.baidu.com/dooy/blog/item/0e770a24f70e3b2cd407421b.html
if (m.Msg == 0xf || m.Msg == 0x133)
{
IntPtr hDC = GetWindowDC(m.HWnd);
if (hDC.ToInt32() == 0) //如果取设备上下文失败则返回
{
return;
}
// 建立Graphics对像
Graphics g = Graphics.FromHdc(hDC);
Rectangle rect = new Rectangle(0, 0, Width - 1, Height - 1);
Rectangle rectCenter = new Rectangle(1, 1, Width - 3, Height - 2);
Color boxBackColor = Enabled ? _BoxBackColor : Color.FromArgb(255, 200, 200, 200);
Color boxCenterColor = Enabled ? _BoxCenterColor : Color.FromArgb(255, 200, 200, 200);
Color fontColor = Enabled ? _FontColor : Color.FromArgb(255, 127, 127, 127);
Color arrorColor = Enabled ? _ArrowColor : Color.FromArgb(255, 127, 127, 127);
// 填充框外颜色(预留,可扩展为带圆角矩形的阴影特效)
g.DrawRectangle(new Pen(_BoxBackColor), rect);
// 填充框内颜色
if (this.DropDownStyle == ComboBoxStyle.DropDownList)
{
g.FillRectangle(new SolidBrush(boxCenterColor), rectCenter);
}
// 填充下拉按钮
g.FillRectangle(new SolidBrush(boxCenterColor), Width - Height + 2, 1, Height - 3, Height - 2);
// 绘制边框
//ControlPaint.DrawBorder(g, rect, _BorderColor, _BorderStyle);
g.DrawPolygon(new Pen(new SolidBrush(_BorderColor), 1), new Point[] {
new Point(0, 0), new Point(Width, 0), new Point(Width, Height), new Point(0, Height), new Point(0, 1) });
// 绘制下拉按钮边框
//ControlPaint.DrawBorder(g, new Rectangle(Width - Height + 3, 0, Height - 3, Height), Color.Red, ButtonBorderStyle.Solid);
// 绘制下拉按钮坚线
g.DrawLine(new Pen(_BorderColor, 1), new PointF(this.Width - this.Height + 3, 0), new PointF(this.Width - this.Height + 3, this.Height));
string selValue = this.Text;
//string text = Enabled ? selValue : "";
string text = selValue;
// 绘制下拉按钮箭头
if (_ArrowFlag)
{
g.DrawLines(new Pen(arrorColor, _ArrowWidth), new PointF[] {
new PointF(this.Width - 6, this.Height / 2 - 2),
new PointF(this.Width - 10, this.Height / 2 + 2),
new PointF(this.Width - 14, this.Height / 2 - 2)
});
}
if (this.DropDownStyle == ComboBoxStyle.DropDownList)
{
// 绘制文本
g.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit;
g.DrawString(text, Font, new SolidBrush(fontColor), 1, 3);
//// 绘制选中文本及背景 // 废弃
//if (this.SelectionLength > 0 && SelectionStart >= 0 && SelectionStart + SelectionLength <= text.Length)
//{
// var sizeLeft = g.MeasureString(text.Substring(0, SelectionStart), Font);
// var sizeSelect = g.MeasureString(text.Substring(SelectionStart, SelectionLength), Font);
// var left = sizeLeft.Width == 0 ? 3 : sizeLeft.Width - 1;
// var width = sizeSelect.Width - 3;
// Rectangle selectRect = new Rectangle((int)left, 3, (int)width, (int)sizeSelect.Height - 1);
// g.FillRectangle(new SolidBrush(Color.FromArgb(51, 153, 255)), selectRect);
// g.DrawString((text.Substring(SelectionStart, SelectionLength)), Font, new SolidBrush(Color.White), left - 2, 3);
//}
}
ReleaseDC(m.HWnd, hDC);
}
else
{
}
}
catch (Exception ex) { }
//if (m.Msg == 0x0014) // 禁掉清除背景消息
// return;
base.WndProc(ref m);
}
private void InitializeComponent()
{
this.SuspendLayout();
this.ResumeLayout(false);
}
}
}
@@ -0,0 +1,324 @@
using NaiBa.Util.Extension;
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Work.Extension;
namespace Work.UserComponents
{
public partial class UcComboBoxMutiSelect : ComboBox
{
//private bool _IsMultiSelect;
//public bool IsMultiSelect { get => _IsMultiSelect; set => _IsMultiSelect = value; }
string defaultText = "全部";
[Browsable(true), Description("默认文本"), Category("自定义分组")]
public string DefaultText
{
get { return defaultText; }
set
{
defaultText = value;
this.Text = defaultText;
this.Invalidate();
}
}
public List<object> SelectItems
{
get
{
if (this.checkedListBox == null)
return this.Items.Cast<object>().ToList();
List<object> lstObj = new List<object>();
for (int i = 0; i < checkedListBox.Items.Count; i++)
{
if (checkedListBox.GetItemChecked(i))
{
lstObj.Add(checkedListBox.Items[i]);
}
}
return lstObj;
}
}
Label lblX = null;
CheckedListBox checkedListBox = null;
public UcComboBoxMutiSelect()
{
SetStyle(ControlStyles.DoubleBuffer |
ControlStyles.OptimizedDoubleBuffer |
ControlStyles.AllPaintingInWmPaint, true);
UpdateStyles();
this.Text = DefaultText;
this.DropDownWidth = 1;
this.DropDownHeight = 1;
this.DropDown += UcComboBoxMutiSelect_DropDown;
this.DropDownClosed += UcComboBoxMutiSelect_DropDownClosed;
Task.Run(() =>
{
for (int i = 0; i < 50; i++)
{
System.Threading.Thread.Sleep(100);
var parentForm = FindForm();
if (parentForm != null && parentForm.Visible == true)
{
Invoke(new Action(() =>
{
UpdateClearLabel();
}));
break;
}
}
this.Move += UcComboBoxMutiSelect_Move;
this.Resize += UcComboBoxMutiSelect_Resize;
this.SizeChanged += UcComboBoxMutiSelect_SizeChanged;
this.VisibleChanged += UcComboBoxMutiSelect_VisibleChanged;
this.ParentChanged += UcComboBoxMutiSelect_ParentChanged;
this.Disposed += UcComboBoxMutiSelect_Disposed;
});
}
private void UcComboBoxMutiSelect_Disposed(object sender, EventArgs e)
{
if (lblX != null)
lblX.Dispose();
}
private void UcComboBoxMutiSelect_ParentChanged(object sender, EventArgs e)
{
//lblX.Parent.Controls.Remove(lblX);
//lblX.Dispose();
//lblX = null;
if (this != null && !this.IsDisposed && this.Parent != null)
{
this.GetParentNotTable().Controls.Add(lblX);
UpdateClearLabel();
}
}
private void UcComboBoxMutiSelect_VisibleChanged(object sender, EventArgs e)
{
if (lblX != null && lblX.Visible != this.Visible)
lblX.Visible = this.Visible;
}
private void UcComboBoxMutiSelect_SizeChanged(object sender, EventArgs e)
{
UpdateClearLabel();
}
private void UcComboBoxMutiSelect_Resize(object sender, EventArgs e)
{
UpdateClearLabel();
}
private void UcComboBoxMutiSelect_Move(object sender, EventArgs e)
{
UpdateClearLabel();
}
private void UpdateClearLabel()
{
if (lblX == null || lblX.Disposing || lblX.IsDisposed)
{
lblX = new Label();
lblX.Click += LblX_Click;
//lblX.BorderStyle = BorderStyle.FixedSingle;
lblX.Text = "×";
lblX.ForeColor = Color.FromArgb(63, 126, 255);
lblX.BackColor = this.BackColor;
lblX.AutoSize = false;
//lblX.AutoSize = true;
//lblX.Width = 17;
lblX.Width = 15;
lblX.Height = 19;
lblX.SendToBack();
//Form form = this.FindForm();
//form.Controls.Add(lblX);
var p = this.GetParentNotTable();
if (p != null)
p.Controls.Add(lblX);
}
Point relativeLocation = this.GetRelativePosition(this.GetParentNotTable());
lblX.Location = new Point(relativeLocation.X + this.Width - 19 - lblX.Width, relativeLocation.Y + (this.Height - lblX.Height) / 2);
lblX.Visible = this.Visible;
lblX.BringToFront();
}
private void LblX_Click(object sender, EventArgs e)
{
if (this.lblX.Text == "×")
{
this.lblX.Text = "↶";
this.Text = "";
}
else
{
this.lblX.Text = "×";
this.Text = DefaultText;
}
}
private void UcComboBoxMutiSelect_DropDownClosed(object sender, EventArgs e)
{
if (checkedListBox != null)
{
var parentForm = this.FindForm();
Point mousePosition = parentForm.PointToClient(Cursor.Position);
Point relativeLocation = checkedListBox.GetRelativePosition();
if (mousePosition.X < relativeLocation.X || mousePosition.X > relativeLocation.X + checkedListBox.Width ||
mousePosition.Y < relativeLocation.Y || mousePosition.Y > relativeLocation.Y + checkedListBox.Height)
{
checkedListBox.Visible = false;
}
}
}
private void UcComboBoxMutiSelect_DropDown(object sender, EventArgs e)
{
var parentForm = this.FindForm();
if (checkedListBox == null)
{
checkedListBox = new CheckedListBox();
checkedListBox.Visible = false;
checkedListBox.CheckOnClick = true;
checkedListBox.ItemCheck += checkedListBox_ItemCheck;
checkedListBox.MouseLeave += checkedListBox_MouseLeave;
checkedListBox.MouseEnter += CheckedListBox_MouseEnter;
checkedListBox.MouseMove += CheckedListBox_MouseMove;
//checkedListBox.MouseUp += new MouseEventHandler(checkedListBox_MouseUp);
parentForm.Controls.Add(checkedListBox);
}
string str1 = string.Join(",", this.Items.Cast<object>().Select(o => o.ParseToString()));
string str2 = string.Join(",", this.checkedListBox.Items.Cast<object>().Select(o => o.ParseToString()));
if (str1 != str2)
{
checkedListBox.Items.Clear();
if (Items.Count > 0)
checkedListBox.ItemCheck -= checkedListBox_ItemCheck;
foreach (var item in this.Items)
{
if (Items[Items.Count - 1] == item)
checkedListBox.ItemCheck += checkedListBox_ItemCheck;
checkedListBox.Items.Add(item.ParseToString(), true);
}
}
// 防止一起设置每次都要重新拼接字符串
if (checkedListBox.Items.Count > 0)
checkedListBox.ItemCheck -= checkedListBox_ItemCheck;
for (int index = 0; index < checkedListBox.Items.Count; index++)
{
if (index == checkedListBox.Items.Count - 1)
checkedListBox.ItemCheck += checkedListBox_ItemCheck;
var item = checkedListBox.Items[index];
if (this.Text == DefaultText || this.Text.Split(new string[] { ";", ";", ",", "," }, StringSplitOptions.RemoveEmptyEntries).ToList().Contains(item.ParseToString()))
checkedListBox.SetItemChecked(index, true);
else
checkedListBox.SetItemChecked(index, false);
}
// 计算宽度
int maxItemWidth = 0;
for (int index = 0; index < checkedListBox.Items.Count; index++)
{
var wth = TextRenderer.MeasureText(checkedListBox.Items[index].ToString(), checkedListBox.Font).Width + 40;
if (wth > maxItemWidth)
maxItemWidth = wth;
}
checkedListBox.SendToBack();
checkedListBox.Visible = true;
// 确定弹出列表框的大小和位置
//checkedListBox.Size = new Size(Math.Max(80, this.Width), Math.Min(300, checkedListBox.PreferredHeight));
checkedListBox.Size = new Size(Math.Max(this.Width, maxItemWidth), Math.Min(300, checkedListBox.PreferredHeight));
Point relativeLocation = this.GetRelativePosition();
if (parentForm.Height - relativeLocation.Y >= this.Height + checkedListBox.Size.Height + 20)
relativeLocation = new Point(relativeLocation.X, relativeLocation.Y + this.Height);
else
relativeLocation = new Point(relativeLocation.X, relativeLocation.Y - checkedListBox.Size.Height);
checkedListBox.Location = relativeLocation;
checkedListBox.BringToFront();
//parentForm.ActiveControl = checkedListBox;
//checkedListBox.Focus();
}
private void CheckedListBox_MouseMove(object sender, MouseEventArgs e)
{
//this.DropDownClosed -= UcComboBoxMutiSelect_DropDownClosed;
}
private void CheckedListBox_MouseEnter(object sender, EventArgs e)
{
//this.DropDownClosed -= UcComboBoxMutiSelect_DropDownClosed;
}
private void checkedListBox_MouseLeave(object sender, EventArgs e)
{
////this.DropDownClosed += UcComboBoxMutiSelect_DropDownClosed;
////统计选取的项目
//string str = "";
//for (int i = 0; i < checkedListBox.Items.Count; i++)
//{
// if (checkedListBox.GetItemChecked(i))
// {
// str += $"{checkedListBox.Items[i].ParseToString()};";
// }
//}
//this.Text = str;
checkedListBox.Visible = false;
this.OnDropDownClosed(null);
}
private void checkedListBox_ItemCheck(object sender, EventArgs e)
{
//统计选取的项目
Task.Run(() =>
{
Thread.Sleep(100);
Invoke(new Action(() =>
{
string str = "";
for (int i = 0; i < checkedListBox.Items.Count; i++)
{
if (checkedListBox.GetItemChecked(i))
{
str += $"{checkedListBox.Items[i].ParseToString()};";
}
}
this.Text = str.Trim(';');
string str1 = string.Join(";", this.Items.Cast<object>().Select(o => o.ParseToString()));
if (this.Text.Trim(';') == str1)
{
this.Text = this.DefaultText;
}
}));
});
}
}
}
@@ -0,0 +1,37 @@
namespace Work.UserComponents
{
partial class UcComboBoxMutiSelect
{
/// <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
}
}
@@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Work.UserComponents
{
public partial class UcDataGridViewCheckBoxColumn : DataGridViewCheckBoxColumn
{
public UcDataGridViewCheckBoxColumn()
{
InitializeComponent();
}
public UcDataGridViewCheckBoxColumn(IContainer container)
{
container.Add(this);
InitializeComponent();
}
}
}
@@ -0,0 +1,37 @@
namespace Work.UserComponents
{
partial class UcDataGridViewCheckBoxColumn
{
/// <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
}
}
@@ -0,0 +1,115 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace Work.UserComponents
{
/// <summary>
/// 可以改变边框颜色的groupbox
/// </summary>
public partial class UcGroupBoxEx : GroupBox
{
private Color _BorderColor = Color.FromArgb(33, 202, 99);
private GroupBoxBorderStyle _BorderStyle = GroupBoxBorderStyle.ROUND;
[Browsable(true), Description("边框颜色"), Category("自定义分组")]
public Color BorderColor
{
get { return _BorderColor; }
set
{
_BorderColor = value;
this.Invalidate();
}
}
[Browsable(true), Description("边框样式"), Category("自定义分组")]
public GroupBoxBorderStyle BorderStyle
{
get { return _BorderStyle; }
set
{
_BorderStyle = value;
this.Invalidate();
}
}
public UcGroupBoxEx()
{
InitializeComponent();
}
public UcGroupBoxEx(IContainer container)
{
container.Add(this);
InitializeComponent();
}
/// <summary>
/// 重写OnPaint绘制自定义效果
/// </summary>
/// <param name="e"></param>
protected override void OnPaint(PaintEventArgs e)
{
e.Graphics.Clear(this.BackColor);
// 绘制字体
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.ClearTypeGridFit; // 或者 AntiAliasGridFit // 平滑字体
e.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), 10, 1);
// 计算文本大小
var vSize = e.Graphics.MeasureString(this.Text, this.Font);
Pen vPen = new Pen(this._BorderColor);
// 绘制矩形
if (_BorderStyle == GroupBoxBorderStyle.SQUARE)
{
e.Graphics.DrawLine(vPen, 2, vSize.Height / 2, 8, vSize.Height / 2); // 标题左侧
e.Graphics.DrawLine(vPen, vSize.Width + 8, vSize.Height / 2, this.Width - 3, vSize.Height / 2); // 标题右侧
e.Graphics.DrawLine(vPen, 2, vSize.Height / 2, 2, this.Height - 3); // 左侧
e.Graphics.DrawLine(vPen, 2, this.Height - 3, this.Width - 3, this.Height - 3); // 底部
e.Graphics.DrawLine(vPen, this.Width - 3, vSize.Height / 2, this.Width - 3, this.Height - 3); // 右侧
}
// 绘制圆角矩形
else
{
e.Graphics.DrawLine(vPen, 4, vSize.Height / 2, 8, vSize.Height / 2); // 标题左侧
e.Graphics.DrawLine(vPen, vSize.Width + 8, vSize.Height / 2, this.Width - 5, vSize.Height / 2); // 标题右侧
e.Graphics.DrawLine(vPen, 2, vSize.Height / 2 + 2, 2, this.Height - 5); // 左侧
e.Graphics.DrawLine(vPen, 4, this.Height - 3, this.Width - 5, this.Height - 3); // 底部
e.Graphics.DrawLine(vPen, this.Width - 3, vSize.Height / 2 + 2, this.Width - 3, this.Height - 5); // 右侧
// 边角直线模拟圆角
e.Graphics.DrawLine(vPen, 2, vSize.Height / 2 + 2, 4, vSize.Height / 2); // 左上角
e.Graphics.DrawLine(vPen, this.Width - 5, vSize.Height / 2, this.Width - 3, vSize.Height / 2 + 2); // 右上角
e.Graphics.DrawLine(vPen, this.Width - 3, this.Height - 5, this.Width - 5, this.Height - 3); // 右下角
e.Graphics.DrawLine(vPen, 4, this.Height - 3, 2, this.Height - 5); // 左下角
}
}
protected override void WndProc(ref Message m)
{
base.WndProc(ref m);
try
{
// WM_NCCALCSIZE 0x0083 当计算某个窗口的客户区大小和位置时发送此消息
// windows消息值表,可参考:http://hi.baidu.com/dooy/blog/item/0e770a24f70e3b2cd407421b.html
if (m.Msg == 0x83)
{
this.Invalidate();
}
}
catch { }
}
public enum GroupBoxBorderStyle
{
ROUND,
SQUARE,
}
}
}
+36
View File
@@ -0,0 +1,36 @@
namespace Work.UserComponents
{
partial class UcGroupBoxEx
{
/// <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
}
}
@@ -0,0 +1,209 @@
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.Runtime.InteropServices;
namespace Work.UserComponents
{
public partial class UcTabControl : TabControl
{
public UcTabControl()
{
InitializeComponent();
base.SetStyle(
ControlStyles.UserPaint | // 控件将自行绘制,而不是通过操作系统来绘制
ControlStyles.OptimizedDoubleBuffer | // 该控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁
ControlStyles.AllPaintingInWmPaint | // 控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁
ControlStyles.ResizeRedraw | // 在调整控件大小时重绘控件
ControlStyles.SupportsTransparentBackColor, // 控件接受 alpha 组件小于 255 的 BackColor 以模拟透明
true); // 设置以上值为 true
base.UpdateStyles();
//this.SizeMode = TabSizeMode.Fixed;
this.MouseDown += UcTabControl_MouseDown;
}
private void UcTabControl_MouseDown(object sender, MouseEventArgs e)
{
if (this.TabCount == 0)
return;
if (e.Button == MouseButtons.Left)
{
if (!showCloseButton)
return;
int x = e.X, y = e.Y;
Rectangle rect = this.GetTabRect(this.SelectedIndex);
Rectangle closeRect = new Rectangle(rect.X + rect.Width - 16, rect.Y + rect.Height / 2 - 4, 8, 8);
if (x >= closeRect.X && y >= closeRect.Y && x <= closeRect.X + closeRect.Width && y <= closeRect.Y + closeRect.Height)
{
this.TabPages.Remove(this.SelectedTab);
}
}
}
private Color backgroundColor = Color.FromArgb(251, 251, 251);
[Browsable(true), Category("自定义分组"), Description("Tab控件背景")]
public Color BackgroundColor
{
get { return backgroundColor; }
set
{
backgroundColor = value;
this.Invalidate();
}
}
private Color tabSelectColor = Color.Red;
[Browsable(true), Category("自定义分组"), Description("Tab选中颜色")]
public Color TabSelectColor
{
get { return tabSelectColor; }
set
{
tabSelectColor = value;
this.Invalidate();
}
}
private Color tabTextColor = Color.Gray;
[Browsable(true), Category("自定义分组"), Description("Tab选中颜色")]
public Color TabTextColor
{
get { return tabTextColor; }
set
{
tabTextColor = value;
this.Invalidate();
}
}
private Color tabSelectTextColor = Color.Gray;
[Browsable(true), Category("自定义分组"), Description("Tab选中颜色")]
public Color TabSelectTextColor
{
get { return tabSelectTextColor; }
set
{
tabSelectTextColor = value;
this.Invalidate();
}
}
private bool showCloseButton = false;
[Browsable(true), Category("自定义分组"), Description("显示关闭页面按钮")]
public bool ShowCloseButton
{
get { return showCloseButton; }
set
{
showCloseButton = value;
if (showCloseButton)
this.Padding = new Point(10, this.Padding.Y);
else
this.Padding = new Point(6, this.Padding.Y);
this.Invalidate();
}
}
#region 去掉或减小TabControl的边框(去掉的话+-3)
protected override void WndProc(ref Message m)
{
if ((m.Msg == TCM_ADJUSTRECT))
{
RECT rc = (RECT)m.GetLParam(typeof(RECT));
//Adjust these values to suit, dependant upon Appearance
rc.Left -= 2;
rc.Right += 0;
rc.Top -= 0;
rc.Bottom += 0;
Marshal.StructureToPtr(rc, m.LParam, true);
}
base.WndProc(ref m);
}
private const Int32 TCM_FIRST = 0x1300;
private const Int32 TCM_ADJUSTRECT = (TCM_FIRST + 40);
private struct RECT
{
public Int32 Left;
public Int32 Top;
public Int32 Right;
public Int32 Bottom;
}
#endregion
Size oldSize = new Size();
protected override void OnPaint(PaintEventArgs e)
{
if (TabPages.Count > 0 && oldSize.Width != this.Size.Width && this.SizeMode == TabSizeMode.Fixed)
{
//this.SizeMode = TabSizeMode.Fixed;
this.ItemSize = new Size((int)Math.Floor(1.0 * (this.Width - 4) / TabPages.Count), 40);
oldSize.Width = this.Size.Width;
}
// 绘制背景
e.Graphics.FillRectangle(new SolidBrush(backgroundColor), new RectangleF(0, 0, this.Width, this.Height));
// 绘制边框
//e.Graphics.DrawRectangle(new Pen(backgroundColor), 0, 0, this.Width, this.Height);
//e.Graphics.DrawLine(new Pen(tabSelectColor), 2, this.GetTabRect(0).Bottom, this.Width - 6, this.GetTabRect(0).Bottom);
// 绘制tab控件
for (int i = 0; i < this.TabCount; i++)
{
// Calculate text position
Rectangle bounds = this.GetTabRect(i);
PointF textPoint = new PointF();
SizeF textSize = TextRenderer.MeasureText(this.TabPages[i].Text, this.Font);
// 加上每个标签的左偏移量X
textPoint.X = bounds.X + (bounds.Width - textSize.Width) / 2;
textPoint.Y = bounds.Y + (bounds.Height - textSize.Height) / 2;
if (showCloseButton)
textPoint.X -= 5;
// 绘制标题
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
if (this.SelectedIndex == i)
e.Graphics.DrawString(this.TabPages[i].Text, this.Font, new SolidBrush(TabSelectTextColor), textPoint.X, textPoint.Y);
else
e.Graphics.DrawString(this.TabPages[i].Text, this.Font, new SolidBrush(tabTextColor), textPoint.X, textPoint.Y);
// 绘制tab框
//e.Graphics.DrawRectangle(Pens.Red, this.GetTabRect(i));
if (this.SelectedIndex == i)
{
for (int j = 0; j < 2; j++)
e.Graphics.DrawLine(new Pen(tabSelectColor),
new Point(this.GetTabRect(i).Left + 0, this.GetTabRect(i).Bottom - j),
new Point(this.GetTabRect(i).Right - 5, this.GetTabRect(i).Bottom - j));
}
// 绘制关闭按钮
if (showCloseButton)
{
using (Pen pen = new Pen(Color.Gray, 1.4f))
{
Point p1 = new Point(bounds.X + bounds.Width - 15, bounds.Y + bounds.Height / 2 - 3);
Point p2 = new Point(bounds.X + bounds.Width - 9, bounds.Y + bounds.Height / 2 + 3);
e.Graphics.DrawLine(pen, p1, p2);
Point p3 = new Point(bounds.X + bounds.Width - 9, bounds.Y + bounds.Height / 2 - 3);
Point p4 = new Point(bounds.X + bounds.Width - 15, bounds.Y + bounds.Height / 2 + 3);
e.Graphics.DrawLine(pen, p3, p4);
}
}
}
}
}
}
+36
View File
@@ -0,0 +1,36 @@
namespace Work.UserComponents
{
partial class UcTabControl
{
/// <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
}
}
@@ -0,0 +1,178 @@
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;
namespace Work.UserComponents
{
public partial class UcTabControlMetro : TabControl
{
public UcTabControlMetro()
{
InitializeComponent();
base.SetStyle(
ControlStyles.UserPaint | // 控件将自行绘制,而不是通过操作系统来绘制
ControlStyles.OptimizedDoubleBuffer | // 该控件首先在缓冲区中绘制,而不是直接绘制到屏幕上,这样可以减少闪烁
ControlStyles.AllPaintingInWmPaint | // 控件将忽略 WM_ERASEBKGND 窗口消息以减少闪烁
ControlStyles.ResizeRedraw | // 在调整控件大小时重绘控件
ControlStyles.SupportsTransparentBackColor, // 控件接受 alpha 组件小于 255 的 BackColor 以模拟透明
true); // 设置以上值为 true
base.UpdateStyles();
//this.SizeMode = TabSizeMode.Fixed;
}
private Color backgroundColor = Color.FromArgb(251, 251, 251);
[Browsable(true), Category("自定义分组"), Description("Tab控件背景")]
public Color BackgroundColor
{
get { return backgroundColor; }
set
{
backgroundColor = value;
this.Invalidate();
}
}
private Color borderColor = Color.FromArgb(0, 174, 157);
[Browsable(true), Category("自定义分组"), Description("Tab控件边框颜色")]
public Color BorderColor
{
get { return borderColor; }
set
{
borderColor = value;
this.Invalidate();
}
}
private Color tabSelectColor = Color.Red;
[Browsable(true), Category("自定义分组"), Description("Tab选中颜色")]
public Color TabSelectColor
{
get { return tabSelectColor; }
set
{
tabSelectColor = value;
this.Invalidate();
}
}
private Color tabSelectTextColor = Color.Gray;
[Browsable(true), Category("自定义分组"), Description("Tab选中文字颜色")]
public Color TabSelectTextColor
{
get { return tabSelectTextColor; }
set
{
tabSelectTextColor = value;
this.Invalidate();
}
}
private Color tabUnSelectTextColor = Color.White;
[Browsable(true), Category("自定义分组"), Description("Tab未选中文字颜色")]
public Color TabUnSelectTextColor
{
get { return tabUnSelectTextColor; }
set
{
tabUnSelectTextColor = value;
this.Invalidate();
}
}
private bool showCloseButton = false;
[Browsable(true), Category("自定义分组"), Description("显示关闭页面按钮")]
public bool ShowCloseButton
{
get { return showCloseButton; }
set
{
showCloseButton = value;
this.Invalidate();
}
}
Size oldSize = new Size();
protected override void OnPaint(PaintEventArgs e)
{
if (TabPages.Count > 0 && oldSize.Width != this.Size.Width && this.SizeMode == TabSizeMode.Fixed)
{
//this.SizeMode = TabSizeMode.Fixed;
this.ItemSize = new Size((int)Math.Floor(1.0 * (this.Width - 4) / TabPages.Count), 40);
oldSize.Width = this.Size.Width;
}
// 绘制背景
e.Graphics.FillRectangle(new SolidBrush(backgroundColor), new RectangleF(0, 0, this.Width, this.Height));
// 绘制边框
int startX = this.Margin.Left;
int startY = this.Margin.Top;
if (this.TabCount > 0)
{
startX = this.GetTabRect(0).Top;
startY = this.GetTabRect(0).Bottom;
}
e.Graphics.DrawRectangle(new Pen(tabSelectColor), startX, startY, this.Width - this.Margin.Right - startX, this.Height - this.Margin.Bottom - startY);
// 绘制tab控件
for (int i = 0; i < this.TabCount; i++)
{
// 计算tab标题位置
Rectangle bounds = this.GetTabRect(i);
PointF textPoint = new PointF();
SizeF textSize = TextRenderer.MeasureText(this.TabPages[i].Text, this.Font);
// 加上每个标签的左偏移量X
textPoint.X = bounds.X + (bounds.Width - textSize.Width) / 2;
textPoint.Y = bounds.Y + (bounds.Height - textSize.Height) / 2;
// 当前选中的tab
if (this.SelectedIndex == i)
{
// 绘制tab框
var rect = this.GetTabRect(i);
// 底部和背景色相同
e.Graphics.DrawLine(new Pen(backgroundColor), new Point(rect.Left, rect.Bottom), new Point(rect.Right, rect.Bottom));
e.Graphics.DrawLine(new Pen(tabSelectColor), new Point(rect.Left, rect.Bottom), new Point(rect.Left, rect.Top));
e.Graphics.DrawLine(new Pen(tabSelectColor), new Point(rect.Left, rect.Top), new Point(rect.Right, rect.Top));
e.Graphics.DrawLine(new Pen(tabSelectColor), new Point(rect.Right, rect.Top), new Point(rect.Right, rect.Bottom));
// 绘制tab标题文字
//e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
e.Graphics.DrawString(this.TabPages[i].Text, this.Font, new SolidBrush(tabSelectTextColor), textPoint.X, textPoint.Y);
}
else
{
// 绘制tab框
e.Graphics.FillRectangle(new SolidBrush(tabSelectColor), this.GetTabRect(i));
// 绘制tab标题文字
//e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.SystemDefault;
e.Graphics.TextRenderingHint = System.Drawing.Text.TextRenderingHint.AntiAliasGridFit;
e.Graphics.DrawString(this.TabPages[i].Text, this.Font, new SolidBrush(tabUnSelectTextColor), textPoint.X, textPoint.Y);
}
// 绘制关闭按钮
if (showCloseButton)
{
using (Pen pen = new Pen(Color.Gray, 1f))
{
Point p1 = new Point(bounds.X + 10, bounds.Y + 10);
Point p2 = new Point(bounds.X + bounds.Width - 10, bounds.Y + bounds.Height - 10);
e.Graphics.DrawLine(pen, p1, p2);
Point p3 = new Point(bounds.X + 10, bounds.Y + bounds.Height - 10);
Point p4 = new Point(bounds.X + bounds.Width - 10, bounds.Y + 10);
e.Graphics.DrawLine(pen, p3, p4);
}
}
}
}
}
}
@@ -0,0 +1,36 @@
namespace Work.UserComponents
{
partial class UcTabControlMetro
{
/// <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
}
}
+769
View File
@@ -0,0 +1,769 @@
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;
using System.Threading;
namespace Work.UserComponents
{
/// <summary>
/// 基于树视图的任务控件
/// </summary>
public partial class UcTreeView : TreeView
{
#region //construckor
/// <summary>
/// 自定义树视图控件构造函数
/// </summary>
public UcTreeView()
{
FullRowSelect = true;
ShowLines = true;
// 开启双缓冲等
this.SetStyle(ControlStyles.OptimizedDoubleBuffer | ControlStyles.EnableNotifyMessage | ControlStyles.ResizeRedraw | ControlStyles.AllPaintingInWmPaint, true);
this.DrawMode = TreeViewDrawMode.OwnerDrawAll;
this.ItemHeight = 32;
this.ShowLines = true;
this.AfterExpand += UserTreeView_AfterExpand;
this.AfterSelect += UserTreeView_AfterSelect;
this.Layout += UserTreeView_Layout;
if (Properties.Resources.ResourceManager.GetObject("tree_default_icon_select") != null)
defaultNodeImageSelect = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_default_icon_select");
if (Properties.Resources.ResourceManager.GetObject("tree_default_icon") != null)
defaultNodeImage = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_default_icon");
}
protected override void OnNotifyMessage(Message m)
{
if (m.Msg != 0x14)
{
base.OnNotifyMessage(m);
}
}
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000;
return cp;
}
}
private void UserTreeView_AfterSelect(object sender, TreeViewEventArgs e)
{
if (e.Node.Parent != null)
dicSelectNodeId[e.Node.Parent] = e.Node;
}
#endregion
#region //event
// 定义委托
public delegate void NodeGroupClickHandle(object sender, TreeViewEventArgs e);
// 定义事件
public event NodeGroupClickHandle NodeGroupClick;
// 执行事件
protected virtual void OnNodeGroupClick(TreeViewEventArgs e)
{
if (NodeGroupClick != null)
{
NodeGroupClick(this, e);
}
}
private void UserTreeView_Layout(object sender, LayoutEventArgs e)
{
if (!DesignMode)
{
foreach (TreeNode node in this.Nodes)
{
if (node != null)
{
if (allNodes.Contains(node) == false)
allNodes.Add(node);
}
foreach (TreeNode childNode in node.Nodes)
{
if (node == null)
continue;
if (!dicNodeImageSelect.Keys.Contains(childNode))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text + "_select") != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text + "_select");
dicNodeImageSelect[childNode] = bitmap;
}
}
if (!dicNodeImage.Keys.Contains(childNode))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text) != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject("tree_" + childNode.Text);
dicNodeImage[childNode] = bitmap;
}
}
}
}
}
}
private void UserTreeView_AfterExpand(object sender, TreeViewEventArgs e)
{
BeginUpdate();
if (HideCollapsedGroup && !DesignMode)
{
for (int i = 0; i < this.Nodes.Count; i++)
{
if (e.Node != this.Nodes[i])
{
this.Nodes.Remove(this.Nodes[i]);
i--;
}
}
}
foreach (TreeNode node in this.AllNodes)
{
if (node == null)
continue;
if (node != e.Node)
{
node.Collapse(true);
}
else
{
if (this.SelectedNode == null || this.SelectedNode.Parent == node)
continue;
else if (dicSelectNodeId.Keys.Contains(node))
this.SelectedNode = dicSelectNodeId[node];
else if (node.Nodes.Count > 0)
this.SelectedNode = node.Nodes[0];
}
}
EndUpdate();
}
#endregion
#region //field & property
private Bitmap defaultNodeImage;
private Bitmap defaultNodeImageSelect;
private List<TreeNode> lstTreeNode = new List<TreeNode>();
private Dictionary<TreeNode, TreeNode> dicSelectNodeId = new Dictionary<TreeNode, TreeNode>();
private Dictionary<TreeNode, Bitmap> dicNodeImage = new Dictionary<TreeNode, Bitmap>();
private Dictionary<TreeNode, Bitmap> dicNodeImageSelect = new Dictionary<TreeNode, Bitmap>();
/// <summary>
/// 展开按扭的大小
/// </summary>
private Size ExpandButtonSize = new Size(16, 16);
private Color _ExpandButtonColor = Color.FromArgb(255, 255, 255);
/// <summary>
/// 展开按扭颜色
/// </summary>
[Description("展开按扭颜色"), Category("UserProperty")]
public Color ExpandButtonColor
{
get
{
return _ExpandButtonColor;
}
set
{
if (_ExpandButtonColor != value)
{
_ExpandButtonColor = value;
this.Invalidate();
}
}
}
private Color _GroupBgColor = Color.FromArgb(249, 249, 249);
/// <summary>
/// 分组栏背景色
/// </summary>
[Description("分组栏背景色"), Category("UserProperty")]
public Color GroupBgColor
{
get
{
return _GroupBgColor;
}
set
{
if (_GroupBgColor != value)
{
_GroupBgColor = value;
this.Invalidate();
}
}
}
private Color _ChildNodeSelectedBgColor = Color.FromArgb(34, 148, 203);
/// <summary>
/// 子节点选中背景色
/// </summary>
[Description("子节点选中背景色"), Category("UserProperty")]
public Color ChildNodeSelectedBgColor
{
get
{
return this._ChildNodeSelectedBgColor;
}
set
{
if (_ChildNodeSelectedBgColor != value)
{
_ChildNodeSelectedBgColor = value;
this.Invalidate();
}
}
}
private Color _GroupTitleColor = Color.FromArgb(80, 80, 80);
/// <summary>
/// 分组栏标题色
/// </summary>
[Description("分组栏标题色"), Category("UserProperty")]
public Color GroupTitleColor
{
get
{
return _GroupTitleColor;
}
set
{
if (_GroupTitleColor != value)
{
_GroupTitleColor = value;
this.Invalidate();
}
}
}
private Color _OverForeColor = Color.FromArgb(235, 235, 235);
/// <summary>
/// 鼠标悬停色
/// </summary>
[Description("鼠标悬停色"), Category("UserProperty")]
public Color OverForeColor
{
get
{
return _OverForeColor;
}
set
{
if (_OverForeColor != value)
{
_OverForeColor = value;
this.Invalidate();
}
}
}
private Font groupFont = new Font("宋体", 10.5f);
/// <summary>
/// 组标题字体样式
/// </summary>
[Description("组标题字体样式"), Category("UserProperty")]
public Font GroupFont
{
get
{
return groupFont;
}
set
{
if (groupFont != value)
{
groupFont = value;
this.Invalidate();
}
}
}
private bool _HideCollpasedGroup = false;
[Description("隐藏折叠的组"), Category("UserProperty")]
public bool HideCollapsedGroup
{
get
{
return _HideCollpasedGroup;
}
set
{
if (_HideCollpasedGroup != value)
{
_HideCollpasedGroup = value;
this.Invalidate();
}
}
}
/// <summary>
/// 节点高度
/// </summary>
public new int ItemHeight
{
get
{
return base.ItemHeight;
}
set
{
if (base.ItemHeight != value && value >= 20)
{
base.ItemHeight = value;
this.Invalidate();
}
}
}
private List<TreeNode> allNodes = new List<TreeNode>();
/// <summary>
/// 所有节点列表
/// </summary>
public List<TreeNode> AllNodes { get { return allNodes; } }
#endregion
#region //override
protected override void OnDrawNode(DrawTreeNodeEventArgs e)
{
//base.OnDrawNode(e);
DrawNodeItem(e);
}
protected override void WndProc(ref Message m)
{
if (m.Msg == 0x0201)//单击
{
int wparam = m.LParam.ToInt32();
Point point = new Point(
LOWORD(wparam),
HIWORD(wparam));
//point = PointToClient(point);
TreeNode tn = this.GetNodeAt(point);
if (tn == null)
{
base.WndProc(ref m);
return;
}
if (tn.Level == 0)
{
if (tn.IsExpanded)
{
//tn.Collapse();
}
else
{
tn.Expand();
}
m.Result = IntPtr.Zero;
OnNodeGroupClick(new TreeViewEventArgs(tn, TreeViewAction.ByMouse));
return;
}
else
{
base.WndProc(ref m);
//tn.IsSelected = true;
//this.SelectedNode = tn;
}
this.SelectedNode = tn;
}
else if (m.Msg == 0x0203)//双击
{
int wparam = m.LParam.ToInt32();
Point point = new Point(
LOWORD(wparam),
HIWORD(wparam));
//point = PointToClient(point);
TreeNode tn = this.GetNodeAt(point);
if (tn == null)
{
base.WndProc(ref m);
return;
}
if (tn.Level == 0)
{
m.Result = IntPtr.Zero;
return;
}
else
{
base.WndProc(ref m);
}
this.SelectedNode = tn;
}
else if (m.Msg == 0x0200)//鼠标移动
{
try
{
int wparam = m.LParam.ToInt32();
Point point = new Point(
LOWORD(wparam),
HIWORD(wparam));
//point = PointToClient(point);
TreeNode tn = this.GetNodeAt(point);
if (tn == null)
{
Cursor = Cursors.Default;
// this.SelectedNode = null;
base.WndProc(ref m);
return;
}
Cursor = Cursors.Hand;
//this.SelectedNode = tn;
}
catch { }
}
else if (m.Msg == 0x02A3)//鼠标移出 WM_MOUSELEAVE = $02A3;
{
// this.SelectedNode = null;
base.WndProc(ref m);
return;
}
else
{
base.WndProc(ref m);
}
//WM_LBUTTONDOWN = $0201
//WM_LBUTTONDBLCLK = $0203;
}
#endregion
#region //private method
/// <summary>
/// 自定义绘制节点
/// </summary>
/// <param name="e"></param>
private void DrawNodeItem(DrawTreeNodeEventArgs e)
{
TreeNode tn = e.Node;
if (tn.Level == 0)
{
using (Graphics g = e.Graphics)
{
//g.Clear(this.BackColor); // 清空画布,完整重绘时才能使用
//g.SmoothingMode = SmoothingMode.HighQuality; // 高质量
//g.PixelOffsetMode = PixelOffsetMode.HighQuality; // 高像素偏移质量
//绘制分组的背景
//RenderBackgroundInternalRate(g,
// e.Bounds,
// GroupBgColor,
// GroupBgColor,
// Color.FromArgb(200, 255, 255, 255),
// 0.45f,
// true,
// 300);
int red = GroupBgColor.R;
int green = GroupBgColor.G;
int blue = GroupBgColor.B;
if (red < 127) red += 15; else red -= 15;
if (green < 127) green += 15; else green -= 15;
if (blue < 127) blue += 15; else blue -= 15;
var color = Color.FromArgb(red, green, blue);
RenderBackgroundSolid(g, e.Bounds, color, color, color, false);
//绘制展开按扭
//g.FillEllipse(new SolidBrush(ExpandButtonColor), ExpandButtonBounds(e.Bounds));
//g.DrawEllipse(new Pen(Color.LightGray), ExpandButtonBounds(e.Bounds));
//Point p1;
//Point p2;
//Point p3;
//if (tn.IsExpanded)
//{
// p1 = new Point(ExpandButtonBounds(e.Bounds).X + 3, ExpandButtonBounds(e.Bounds).Bottom - 4);
// p2 = new Point(ExpandButtonBounds(e.Bounds).X + (ExpandButtonSize.Width) / 2, ExpandButtonBounds(e.Bounds).Top + 5);
// p3 = new Point(ExpandButtonBounds(e.Bounds).Right - 3, ExpandButtonBounds(e.Bounds).Bottom - 4);
//}
//else
//{
// p1 = new Point(ExpandButtonBounds(e.Bounds).X + 3, ExpandButtonBounds(e.Bounds).Y + 4);
// p2 = new Point(ExpandButtonBounds(e.Bounds).X + (ExpandButtonSize.Width) / 2, ExpandButtonBounds(e.Bounds).Bottom - 5);
// p3 = new Point(ExpandButtonBounds(e.Bounds).Right - 3, ExpandButtonBounds(e.Bounds).Y + 4);
//}
//GraphicsPath gp = new GraphicsPath();
//gp.AddLine(p1, p2);
//gp.AddLine(p2, p3);
//g.DrawPath(new Pen(Color.FromArgb(255, 150, 0, 0), 2f), gp);
//绘制分组的文本
TextRenderer.DrawText(g, e.Node.Text, this.GroupFont, GroupTitleBounds(e.Bounds), this.GroupTitleColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.EndEllipsis);
}
}
else if (tn.Level == 1)
{
//e.DrawDefault = true;
using (Graphics g = e.Graphics)
{
#region 小奶猫增加权限后,无法自动绘制TreeNode图标,经调试确认,增加此段代码 by ttzhao 2020.7.1
if (!dicNodeImageSelect.Keys.Contains(e.Node))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject(e.Node.Text + "_select") != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject(e.Node.Text + "_select");
dicNodeImageSelect[e.Node] = bitmap;
}
}
if (!dicNodeImage.Keys.Contains(e.Node))
{
// 获取图标
if (Properties.Resources.ResourceManager.GetObject(e.Node.Text) != null)
{
var bitmap = (Bitmap)Properties.Resources.ResourceManager.GetObject(e.Node.Text);
dicNodeImage[e.Node] = bitmap;
}
}
#endregion 小奶猫增加权限后,无法自动绘制TreeNode图标,经调试确认,增加此段代码 by ttzhao 2020.7.1
if (tn.IsSelected)
{
RenderBackgroundSolid(g, e.Bounds, ChildNodeSelectedBgColor, ChildNodeSelectedBgColor, ChildNodeSelectedBgColor, false);
//TextRenderer.DrawText(g, e.Node.Text, new Font(this.Font.FontFamily.Name, this.Font.Size, FontStyle.Underline), e.Bounds, OverForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
TextRenderer.DrawText(g, e.Node.Text, this.Font, ChildTitleBounds(e.Bounds), this.OverForeColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
// 绘制图标
if (dicNodeImageSelect.Keys.Contains(e.Node))
g.DrawImage(dicNodeImageSelect[e.Node], new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
else if (defaultNodeImageSelect != null)
g.DrawImage(defaultNodeImageSelect, new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
}
else
{
RenderBackgroundSolid(g, e.Bounds, GroupBgColor, GroupBgColor, GroupBgColor, false);
//TextRenderer.DrawText(g, e.Node.Text, this.Font, e.Bounds, this.ForeColor, TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
TextRenderer.DrawText(g, e.Node.Text, this.Font, ChildTitleBounds(e.Bounds), this.ForeColor,
TextFormatFlags.Left | TextFormatFlags.VerticalCenter);
// 绘制图标
if (dicNodeImage.Keys.Contains(e.Node))
g.DrawImage(dicNodeImage[e.Node], new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
else if (defaultNodeImage != null)
g.DrawImage(defaultNodeImage, new Rectangle(e.Bounds.X + 30, e.Bounds.Y + 8, 16, 16));
}
}
}
}
/// <summary>
/// 展开按扭区域 一级菜单后面的展开按钮
/// </summary>
/// <param name="childRect"></param>
/// <returns></returns>
private Rectangle ExpandButtonBounds(Rectangle childRect)
{
Rectangle lrect = new Rectangle(new Point(childRect.Right - ExpandButtonSize.Width * 3 / 2, (childRect.Height - ExpandButtonSize.Height) / 2 + childRect.Top), ExpandButtonSize);
return lrect;
}
/// <summary>
/// 取得分组标题绘制空间 一级菜单
/// </summary>
/// <param name="childRect"></param>
/// <returns></returns>
private Rectangle GroupTitleBounds(Rectangle childRect)
{
Rectangle lrect = childRect;
lrect.Width -= ExpandButtonSize.Width * 3 / 2 + 20;
//lrect.Offset(45, 0);
lrect.Offset(12, 0);
return lrect;
}
private Rectangle ChildTitleBounds(Rectangle rect)
{
Rectangle lrect = rect;
lrect.Width -= 50;
lrect.Offset(55, 0);
return lrect;
}
#endregion
#region //draw
internal void RenderBackgroundSolid(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor, bool drawBorder)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
using (SolidBrush brush = new SolidBrush(baseColor))
{
g.FillRectangle(brush, rect);
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
internal void RenderBackgroundInternal(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor,
float basePosition, bool drawBorder, LinearGradientMode mode)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, mode))
{
Color[] colors = new Color[4];
colors[0] = GetColor(baseColor, 0, 35, 24, 9);
colors[1] = GetColor(baseColor, 0, 13, 8, 3);
colors[2] = baseColor;
colors[3] = GetColor(baseColor, 0, 68, 69, 54);
ColorBlend blend = new ColorBlend();
blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
blend.Colors = colors;
brush.InterpolationColors = blend;
g.FillRectangle(brush, rect);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (mode == LinearGradientMode.Vertical)
{
rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)(rect.Width * basePosition);
}
using (SolidBrush brushAlpha =
new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
internal void RenderBackgroundInternalRate(Graphics g, Rectangle rect, Color baseColor, Color borderColor, Color innerBorderColor,
float basePosition, bool drawBorder, float rate)
{
if (drawBorder)
{
rect.Width--;
rect.Height--;
}
using (LinearGradientBrush brush = new LinearGradientBrush(rect, Color.Transparent, Color.Transparent, rate))
{
Color[] colors = new Color[4];
colors[0] = GetColor(baseColor, 0, 35, 24, 9);
colors[1] = GetColor(baseColor, 0, 13, 8, 3);
colors[2] = baseColor;
colors[3] = GetColor(baseColor, 0, 68, 69, 54);
ColorBlend blend = new ColorBlend();
blend.Positions = new float[] { 0.0f, basePosition, basePosition + 0.05f, 1.0f };
blend.Colors = colors;
brush.InterpolationColors = blend;
g.FillRectangle(brush, rect);
}
if (baseColor.A > 80)
{
Rectangle rectTop = rect;
if (true/*mode == LinearGradientMode.Vertical*/)
{
rectTop.Height = (int)(rectTop.Height * basePosition);
}
else
{
rectTop.Width = (int)(rect.Width * basePosition);
}
using (SolidBrush brushAlpha =
new SolidBrush(Color.FromArgb(80, 255, 255, 255)))
{
g.FillRectangle(brushAlpha, rectTop);
}
}
if (drawBorder)
{
using (Pen pen = new Pen(borderColor))
{
g.DrawRectangle(pen, rect);
}
rect.Inflate(-1, -1);
using (Pen pen = new Pen(innerBorderColor))
{
g.DrawRectangle(pen, rect);
}
}
}
private Color GetColor(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > 255) { a = 255; } else { a = a + a0; }
if (r + r0 > 255) { r = 255; } else { r = r + r0; }
if (g + g0 > 255) { g = 255; } else { g = g + g0; }
if (b + b0 > 255) { b = 255; } else { b = b + b0; }
return Color.FromArgb(a, r, g, b);
}
private Color GetColor2(Color colorBase, int a, int r, int g, int b)
{
int a0 = colorBase.A;
int r0 = colorBase.R;
int g0 = colorBase.G;
int b0 = colorBase.B;
if (a + a0 > 255) { a = 255; } else { a = a + a0; }
if (r0 - r < 0) { r = 0; } else { r = r0 - r; }
if (g0 - g < 0) { g = 0; } else { g = g0 - g; }
if (b0 - b < 0) { b = 0; } else { b = b0 - b; }
return Color.FromArgb(a, r, g, b);
}
#endregion
public static int LOWORD(int value)
{
return value & 0xFFFF;
}
public static int HIWORD(int value)
{
return value >> 16;
}
public void ExpandGroup(string groupName)
{
var node = this.AllNodes.FirstOrDefault(n => n.Name == groupName);
if (node == null)
return;
BeginUpdate();
if (!this.Nodes.Contains(node))
this.Nodes.Insert(0, node);
node.Expand();
EndUpdate();
}
}
}
+36
View File
@@ -0,0 +1,36 @@
namespace Work.UserComponents
{
partial class UcTreeView
{
/// <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
}
}