SunnyUI/SunnyUI/Controls/UIDataGridView.cs

648 lines
21 KiB
C#
Raw Normal View History

2020-05-11 21:11:29 +08:00
/******************************************************************************
* SunnyUI
2021-02-20 15:45:47 +08:00
* CopyRight (C) 2012-2021 ShenYongHua().
* QQ群56829229 QQ17612584 EMailSunnyUI@QQ.Com
2020-05-11 21:11:29 +08:00
*
* Blog: https://www.cnblogs.com/yhuse
* Gitee: https://gitee.com/yhuse/SunnyUI
* GitHub: https://github.com/yhuse/SunnyUI
*
* SunnyUI can be used for free under the GPL-3.0 license.
* If you use this code, please keep this note.
* 使
******************************************************************************
* : UIGrid.cs
* :
* : V3.0
2020-05-11 21:11:29 +08:00
* : 2020-01-01
*
* 2020-01-01: V2.2.0
* 2020-04-25: V2.2.4
* 2020-07-15: V2.2.6
2020-07-30 21:21:47 +08:00
* 2020-07-18: V2.2.6
2020-09-17 21:20:47 +08:00
* 2020-08-22: V2.2.7
* 2020-08-28: V2.2.7
* 2021-03-25: V3.0.2
* 2021-04-01: V3.0.2 Enter键代替Tab键跳到下一个单元格
2020-05-11 21:11:29 +08:00
******************************************************************************/
using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;
namespace Sunny.UI
{
public class UIDataGridView : DataGridView, IStyleInterface
2020-05-11 21:11:29 +08:00
{
private readonly UIScrollBar VBar = new UIScrollBar();
private readonly UIHorScrollBarEx HBar = new UIHorScrollBarEx();
2020-05-11 21:11:29 +08:00
public UIDataGridView()
{
BackgroundColor = UIColor.White;
GridColor = UIColor.Blue;
base.Font = UIFontColor.Font;
base.DoubleBuffered = true;
2020-05-11 21:11:29 +08:00
VBar.Parent = this;
VBar.Visible = false;
HBar.FillColor = VBar.FillColor = UIColor.LightBlue;
VBar.ForeColor = UIColor.Blue;
VBar.StyleCustomMode = true;
VBar.ValueChanged += VBarValueChanged;
HBar.Parent = this;
HBar.Visible = false;
HBar.ForeColor = UIColor.Blue;
HBar.StyleCustomMode = true;
HBar.ValueChanged += HBar_ValueChanged;
SetBarPosition();
2020-05-11 21:11:29 +08:00
//支持自定义标题行风格
EnableHeadersVisualStyles = false;
//标题行风格
ColumnHeadersBorderStyle = DataGridViewHeaderBorderStyle.Single;
ColumnHeadersDefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
ColumnHeadersDefaultCellStyle.BackColor = UIColor.Blue;
ColumnHeadersDefaultCellStyle.ForeColor = UIColor.White;
ColumnHeadersDefaultCellStyle.WrapMode = DataGridViewTriState.True;
//标题行行高与OnColumnAdded事件配合
ColumnHeadersHeight = 32;
//数据行行高
RowTemplate.Height = 29;
RowTemplate.MinimumHeight = 29;
AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.None;
//设置奇偶数行颜色
StripeEvenColor = UIColor.White;
StripeOddColor = UIColor.LightBlue;
VerticalScrollBar.ValueChanged += VerticalScrollBar_ValueChanged;
HorizontalScrollBar.ValueChanged += HorizontalScrollBar_ValueChanged;
VerticalScrollBar.VisibleChanged += VerticalScrollBar_VisibleChanged;
HorizontalScrollBar.VisibleChanged += HorizontalScrollBar_VisibleChanged;
}
private void HorizontalScrollBar_VisibleChanged(object sender, EventArgs e)
{
SetScrollInfo();
}
private void VerticalScrollBar_VisibleChanged(object sender, EventArgs e)
{
SetScrollInfo();
}
public void Init()
{
//自动生成行
AutoGenerateColumns = false;
2020-05-11 21:11:29 +08:00
//列占满行
AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill;
2020-05-11 21:11:29 +08:00
//禁止调整数据行行高
AllowUserToResizeRows = false;
2020-05-11 21:11:29 +08:00
//允许调整标题行行宽
AllowUserToResizeColumns = true;
//禁用最后一行空白,自动新增行
AllowUserToAddRows = false;
AllowUserToDeleteRows = false;
2020-05-11 21:11:29 +08:00
//不显示表格线
CellBorderStyle = DataGridViewCellBorderStyle.None;
//禁止行多选
MultiSelect = false;
//不显示数据行标题
RowHeadersVisible = false;
2020-05-11 21:11:29 +08:00
//禁止只读
//ReadOnly = false;
2020-05-11 21:11:29 +08:00
//行选
SelectionMode = DataGridViewSelectionMode.FullRowSelect;
}
2020-05-11 21:11:29 +08:00
private void VerticalScrollBar_ValueChanged(object sender, EventArgs e)
{
VBar.Value = FirstDisplayedScrollingRowIndex;
VerticalScrollBarChanged?.Invoke(this, e);
}
2020-05-11 21:11:29 +08:00
private void VBarValueChanged(object sender, EventArgs e)
{
FirstDisplayedScrollingRowIndex = VBar.Value;
2020-05-11 21:11:29 +08:00
}
private void HorizontalScrollBar_ValueChanged(object sender, EventArgs e)
{
HBar.Value = HorizontalScrollBar.Value;
}
2020-05-11 21:11:29 +08:00
private void HBar_ValueChanged(object sender, EventArgs e)
{
HorizontalScrollBar.Value = HBar.Value;
HorizontalScrollingOffset = HBar.Value;
HorizontalScrollBarChanged?.Invoke(this, e);
}
2020-05-11 21:11:29 +08:00
public event EventHandler HorizontalScrollBarChanged;
public event EventHandler VerticalScrollBarChanged;
2020-05-11 21:11:29 +08:00
public void SetScrollInfo()
{
if (VBar == null || HBar == null)
2020-05-11 21:11:29 +08:00
{
return;
}
if (RowCount > DisplayedRowCount(false))
2020-05-11 21:11:29 +08:00
{
VBar.Maximum = RowCount - DisplayedRowCount(false);
VBar.Value = FirstDisplayedScrollingRowIndex;
VBar.Visible = true;
2020-05-11 21:11:29 +08:00
}
else
{
VBar.Visible = false;
2020-05-11 21:11:29 +08:00
}
if (HorizontalScrollBar.Visible)
{
HBar.Maximum = HorizontalScrollBar.Maximum;
HBar.Value = HorizontalScrollBar.Value;
HBar.BoundsWidth = HorizontalScrollBar.LargeChange;
HBar.LargeChange = HorizontalScrollBar.LargeChange;//.Maximum / VisibleColumnCount();
HBar.Visible = true;
}
else
{
HBar.Visible = false;
}
SetBarPosition();
2020-05-11 21:11:29 +08:00
}
protected override void OnPaint(PaintEventArgs e)
{
base.OnPaint(e);
if (ShowRect)
{
Color color = RectColor;
color = Enabled ? color : UIDisableColor.Fill;
e.Graphics.DrawRectangle(color, new Rectangle(0, 0, Width - 1, Height - 1));
}
}
2020-05-11 21:11:29 +08:00
protected override void OnMouseWheel(MouseEventArgs e)
{
base.OnMouseWheel(e);
/*if (VBar.Visible)
2020-05-11 21:11:29 +08:00
{
if (e.Delta > 10)
{
VBar.SetValue(VBar.Value - VBar.Maximum / 20);
2020-05-11 21:11:29 +08:00
}
else if (e.Delta < -10)
{
VBar.SetValue(VBar.Value + VBar.Maximum / 20);
2020-05-11 21:11:29 +08:00
}
}*/
if (VBar.Visible && ScrollMode == UIDataGridViewScrollMode.Page)
{
if (e.Delta > 10)
{
var lineCount = Rows.GetLastRow(DataGridViewElementStates.Displayed) - FirstDisplayedScrollingRowIndex;
VBar.SetValue(VBar.Value - lineCount + 3);
}
else if (e.Delta < -10)
{
var lineCount = FirstDisplayedScrollingRowIndex - Rows.GetLastRow(DataGridViewElementStates.Displayed);
VBar.SetValue(VBar.Value - lineCount - 3);
}
2020-05-11 21:11:29 +08:00
}
}
[Description("垂直滚动条滚动方式"), Category("SunnyUI")]
[DefaultValue(UIDataGridViewScrollMode.Normal)]
public UIDataGridViewScrollMode ScrollMode { get; set; } = UIDataGridViewScrollMode.Normal;
public enum UIDataGridViewScrollMode
{
/// <summary>
/// 正常
/// </summary>
Normal,
/// <summary>
/// 翻页
/// </summary>
Page
}
2020-05-18 23:25:19 +08:00
protected override void OnRowsAdded(DataGridViewRowsAddedEventArgs e)
{
base.OnRowsAdded(e);
SetScrollInfo();
}
protected override void OnRowsRemoved(DataGridViewRowsRemovedEventArgs e)
{
base.OnRowsRemoved(e);
SetScrollInfo();
}
2020-05-11 21:11:29 +08:00
protected override void OnSizeChanged(EventArgs e)
{
base.OnSizeChanged(e);
SetScrollInfo();
SetBarPosition();
}
protected override void OnColumnStateChanged(DataGridViewColumnStateChangedEventArgs e)
{
base.OnColumnStateChanged(e);
SetScrollInfo();
}
protected override void OnColumnRemoved(DataGridViewColumnEventArgs e)
{
base.OnColumnRemoved(e);
SetScrollInfo();
}
2020-05-11 21:11:29 +08:00
private void SetBarPosition()
{
if (ShowRect)
{
VBar.Left = Width - ScrollBarInfo.VerticalScrollBarWidth() - 2;
VBar.Top = 1;
VBar.Width = ScrollBarInfo.VerticalScrollBarWidth() + 1;
VBar.Height = Height - 2;
VBar.BringToFront();
HBar.Left = 2;
HBar.Height = ScrollBarInfo.HorizontalScrollBarHeight() + 1;
HBar.Width = Width - (VBar.Visible ? VBar.Width : 0) - 2;
HBar.Top = Height - HBar.Height - 2;
HBar.BringToFront();
}
else
{
VBar.Left = Width - ScrollBarInfo.VerticalScrollBarWidth() - 1;
VBar.Top = 0;
VBar.Width = ScrollBarInfo.VerticalScrollBarWidth() + 1;
VBar.Height = Height;
VBar.BringToFront();
HBar.Left = 0;
HBar.Height = ScrollBarInfo.HorizontalScrollBarHeight() + 1;
HBar.Width = Width - (VBar.Visible ? VBar.Width : 0);
HBar.Top = Height - HBar.Height;
HBar.BringToFront();
}
2020-05-11 21:11:29 +08:00
}
protected override void OnColumnAdded(DataGridViewColumnEventArgs e)
{
base.OnColumnAdded(e);
//设置可调整标题行行高
if (ColumnHeadersHeightSizeMode == DataGridViewColumnHeadersHeightSizeMode.AutoSize)
{
ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.DisableResizing;
}
SetScrollInfo();
2020-05-11 21:11:29 +08:00
}
private UIStyle _style = UIStyle.Blue;
/// <summary>
/// 主题样式
/// </summary>
[DefaultValue(UIStyle.Blue), Description("主题样式"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
public UIStyle Style
{
get => _style;
set => SetStyle(value);
}
[DefaultValue(typeof(Color), "White")]
[Description("偶数行显示颜色"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
public Color StripeEvenColor
{
get => RowsDefaultCellStyle.BackColor;
set
{
RowsDefaultCellStyle.BackColor = value;
Invalidate();
}
}
[DefaultValue(typeof(Color), "235, 243, 255")]
[Description("奇数行显示颜色"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
public Color StripeOddColor
{
get => AlternatingRowsDefaultCellStyle.BackColor;
set
{
AlternatingRowsDefaultCellStyle.BackColor = value;
HBar.FillColor = VBar.FillColor = value;
2020-05-11 21:11:29 +08:00
Invalidate();
}
}
public void SetStyle(UIStyle style)
{
if (!style.Equals(UIStyle.Custom))
{
SetStyleColor(UIStyles.GetStyleColor(style));
}
_style = style;
}
public void SetStyleColor(UIBaseStyle uiColor)
{
//列头部颜色
2020-05-11 21:11:29 +08:00
ColumnHeadersDefaultCellStyle.BackColor = uiColor.TitleColor;
ColumnHeadersDefaultCellStyle.ForeColor = uiColor.TitleForeColor;
ColumnHeadersDefaultCellStyle.SelectionBackColor = uiColor.TitleColor;
//行头部颜色
RowHeadersDefaultCellStyle.BackColor = uiColor.PlainColor;
RowHeadersDefaultCellStyle.ForeColor = uiColor.TitleForeColor;
RowHeadersDefaultCellStyle.SelectionBackColor = uiColor.TitleColor;
2020-05-11 21:11:29 +08:00
//数据行选中颜色
DefaultCellStyle.SelectionBackColor = uiColor.GridSelectedColor;
DefaultCellStyle.SelectionForeColor = uiColor.GridSelectedForeColor;
GridColor = RectColor = uiColor.RectColor;
RowsDefaultCellStyle.BackColor = UIColor.White;
AlternatingRowsDefaultCellStyle.BackColor = UIColor.LightBlue;
StripeEvenColor = uiColor.GridStripeEvenColor;
StripeOddColor = uiColor.GridStripeOddColor;
HBar.FillColor = VBar.FillColor = uiColor.GridStripeOddColor;
HBar.ForeColor = VBar.ForeColor = uiColor.PrimaryColor;
2020-05-11 21:11:29 +08:00
Invalidate();
}
/// <summary>
/// 自定义主题风格
/// </summary>
2020-05-11 21:11:29 +08:00
[DefaultValue(false)]
[Description("获取或设置可以自定义主题风格"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
public bool StyleCustomMode { get; set; }
public string Version => UIGlobal.Version;
/// <summary>
/// Tag字符串
/// </summary>
[DefaultValue(null)]
[Description("获取或设置包含有关控件的数据的对象字符串"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
public string TagString { get; set; }
/// <summary>
/// 是否显示边框
/// </summary>
[Description("是否显示边框"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
[DefaultValue(true)]
public bool ShowRect
{
get => BorderStyle == BorderStyle.FixedSingle;
set
{
BorderStyle = value ? BorderStyle.FixedSingle : BorderStyle.None;
Invalidate();
}
}
/// <summary>
/// 是否显示表格线
/// </summary>
[Description("是否显示表格线"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
[DefaultValue(false)]
public bool ShowGridLine
{
get => CellBorderStyle == DataGridViewCellBorderStyle.Single;
set => CellBorderStyle = value ? DataGridViewCellBorderStyle.Single : DataGridViewCellBorderStyle.None;
}
private Color _rectColor = UIColor.Blue;
[DefaultValue(typeof(Color), "80, 160, 255")]
[Description("边框颜色"), Category("SunnyUI")]
2020-05-11 21:11:29 +08:00
public Color RectColor
{
get => _rectColor;
set
{
if (_rectColor != value)
{
_rectColor = value;
Invalidate();
}
}
}
private int selectedIndex = -1;
[Browsable(false)]
public int SelectedIndex
{
get => selectedIndex;
set
{
if (Rows.Count == 0)
{
selectedIndex = -1;
return;
}
if (value >= 0 && value < Rows.Count)
{
Rows[value].Selected = true;
selectedIndex = value;
FirstDisplayedScrollingRowIndex = value;
SelectIndexChange?.Invoke(this, value);
}
else
{
selectedIndex = -1;
}
}
}
protected override void OnDataSourceChanged(EventArgs e)
{
base.OnDataSourceChanged(e);
SetScrollInfo();
selectedIndex = -1;
}
public delegate void OnSelectIndexChange(object sender, int index);
public event OnSelectIndexChange SelectIndexChange;
protected override void OnCellClick(DataGridViewCellEventArgs e)
{
base.OnCellClick(e);
if (e.RowIndex >= 0 && selectedIndex != e.RowIndex)
{
selectedIndex = e.RowIndex;
SelectIndexChange?.Invoke(this, e.RowIndex);
}
}
// protected override void OnGridColorChanged(EventArgs e)
// {
// base.OnGridColorChanged(e);
// _style = UIStyle.Custom;
// }
//
// protected override void OnDefaultCellStyleChanged(EventArgs e)
// {
// base.OnDefaultCellStyleChanged(e);
// _style = UIStyle.Custom;
// }
//
// protected override void OnColumnDefaultCellStyleChanged(DataGridViewColumnEventArgs e)
// {
// base.OnColumnDefaultCellStyleChanged(e);
// _style = UIStyle.Custom;
// }
2020-05-11 21:11:29 +08:00
public DataGridViewColumn AddColumn(string columnName, string dataPropertyName, int fillWeight = 100, DataGridViewContentAlignment alignment = DataGridViewContentAlignment.MiddleCenter, bool readOnly = true)
{
DataGridViewColumn column = new DataGridViewTextBoxColumn();
column.HeaderText = columnName;
column.DataPropertyName = dataPropertyName;
column.Name = columnName;
column.ReadOnly = readOnly;
column.FillWeight = fillWeight;
column.SortMode = DataGridViewColumnSortMode.NotSortable;
column.DefaultCellStyle.Alignment = alignment;
Columns.Add(column);
return column;
}
public DataGridViewColumn AddCheckBoxColumn(string columnName, string dataPropertyName, int fillWeight = 100, bool readOnly = true)
{
DataGridViewColumn column = new DataGridViewCheckBoxColumn();
column.HeaderText = columnName;
column.DataPropertyName = dataPropertyName;
column.Name = columnName;
column.ReadOnly = readOnly;
column.FillWeight = fillWeight;
column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
Columns.Add(column);
return column;
}
2020-07-28 21:01:40 +08:00
public DataGridViewColumn AddButtonColumn(string columnName, string dataPropertyName, int fillWeight = 100, bool readOnly = true)
{
DataGridViewColumn column = new DataGridViewButtonColumn();
column.HeaderText = columnName;
column.DataPropertyName = dataPropertyName;
column.Name = columnName;
column.ReadOnly = readOnly;
column.FillWeight = fillWeight;
column.DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleCenter;
Columns.Add(column);
return column;
}
2020-05-11 21:11:29 +08:00
public void ClearRows()
{
if (DataSource != null)
{
DataSource = null;
}
Rows.Clear();
}
public void ClearColumns()
{
Columns.Clear();
}
public void ClearAll()
{
ClearRows();
ClearColumns();
}
public int AddRow(params object[] values)
{
return Rows.Add(values);
}
protected override bool ProcessDialogKey(Keys keyData)
{
if (EnterAsTab)
{
Keys key = (keyData & Keys.KeyCode);
if (key == Keys.Enter)
{
//交由自定义控件处理
return false;
}
}
return base.ProcessDialogKey(keyData);
}
protected override bool ProcessDataGridViewKey(KeyEventArgs e)
{
if (EnterAsTab)
{
if (e.KeyCode == Keys.Enter)
{
return this.ProcessTabKey(e.KeyData);
}
}
return base.ProcessDataGridViewKey(e);
}
[DefaultValue(false)]
[Description("编辑输入时用Enter键代替Tab键跳到下一个单元格"), Category("SunnyUI")]
public bool EnterAsTab { get; set; }
2020-05-11 21:11:29 +08:00
}
public static class UIDataGridViewHelper
{
public static DataGridViewColumn SetFixedMode(this DataGridViewColumn column, int width)
{
column.AutoSizeMode = DataGridViewAutoSizeColumnMode.None;
column.Width = width;
return column;
}
2020-05-27 17:26:21 +08:00
public static DataGridViewColumn SetSortMode(this DataGridViewColumn column, DataGridViewColumnSortMode sortMode = DataGridViewColumnSortMode.Automatic)
{
column.SortMode = sortMode;
return column;
}
2020-05-11 21:11:29 +08:00
}
}