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 Common
{
/// <summary>
/// radio button单元格
/// </summary>
/// <remarks>绑定数据后不能在构造函数中修改属性</remarks>
public class DataGridViewRadioButtonCell : DataGridViewTextBoxCell
{
Point radioButtonLocation;
Size radioButtonSize;
Point _cellLocation = new Point();
System.Windows.Forms.VisualStyles.RadioButtonState _cbState =
System.Windows.Forms.VisualStyles.RadioButtonState.UncheckedNormal;
#region Property
#region 行为
private DataGridViewTriState _isReadOnly = DataGridViewTriState.NotSet;
/// <summary>
/// 是否只读
/// </summary>
[Category("行为")]
[Description("是否只读")]
[DefaultValue(DataGridViewTriState.NotSet)]
[Browsable(false)]
public DataGridViewTriState IsReadOnly
{
get
{
if (_isReadOnly == DataGridViewTriState.NotSet)
{
if (this.OwningColumn != null && OwningColumn is DataGridViewRadioButtonColumn)
{
_isReadOnly = (this.OwningColumn as DataGridViewRadioButtonColumn).IsReadOnly ? DataGridViewTriState.True : DataGridViewTriState.False;
}
}
return _isReadOnly;
}
set
{
if (value == DataGridViewTriState.NotSet)
{
value = DataGridViewTriState.False;
}
_isReadOnly = value;
}
}
/// <summary>
/// 不允许编辑
/// </summary>
[Browsable(false)]
[DefaultValue(true)]
public override bool ReadOnly
{
get { return true; }
set
{
base.ReadOnly = true;
}
}
private bool _isChecked = false;
/// <summary>
/// 是否选中
/// </summary>
[Category("行为")]
[Description("是否选中")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool Checked
{
get { return _isChecked; }
set
{
//重新界定值
base.Value = value ? "1" : "0";
if (_isChecked != value)
{
_isChecked = value;
if (value
&& this.OwningColumn != null
&& this.DataGridView != null
&& this.OwningColumn is DataGridViewRadioButtonColumn)
{
//单行选择
if ((this.OwningColumn as DataGridViewRadioButtonColumn).SingleOn)
{
foreach (DataGridViewRow dr in this.DataGridView.Rows)
{
if (dr.Index != this.RowIndex)
{
(dr.Cells[this.ColumnIndex] as DataGridViewRadioButtonCell).Checked = false;
}
}
}
}
if (OnRadioButtonClicked != null)
{
OnRadioButtonClicked(this, Checked);
}
if (this.DataGridView != null)
{
this.DataGridView.InvalidateCell(this);
}
}
}
}
private bool _enabled = true;
/// <summary>
/// 是否可用
/// </summary>
[Category("行为")]
[Description("是否可用")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool Enabled
{
get { return _enabled; }
set
{
if (_enabled != value)
{
_enabled = value;
if (this.DataGridView != null)
{
this.DataGridView.InvalidateCell(this);
}
}
}
}
#endregion
/*
/// <summary>
/// 值
/// </summary>
[Category("数据")]
[Description("值")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public new string Value
{
get
{
return (Checked ? "1" : "0");
}
set
{
if (value != null && value.Equals("1"))
{
Checked = true;
}
else
{
Checked = false;
}
}
}
*/
private bool _isDefault = false;
/// <summary>
/// 是否是默认行
/// </summary>
[Category("行为")]
[Description("是否是默认行")]
[DefaultValue(false)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool IsDefault
{
get { return _isDefault; }
set
{
if (_isDefault != value)
{
_isDefault = value;
}
}
}
private bool _display = true;
/// <summary>
/// 是否可见
/// </summary>
[Category("外观")]
[Description("是否可见")]
[DefaultValue(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool Display
{
get { return _display; }
set
{
if (_display != value)
{
_display = value;
if (this.DataGridView != null)
{
this.DataGridView.InvalidateCell(this);
}
}
}
}
public event RadioButtonClickedHandler OnRadioButtonClicked;
/// <summary>
/// 是否已绑定事件
/// </summary>
[DefaultValue(true)]
[Browsable(false)]
public bool EventIsNull
{
get
{
return OnRadioButtonClicked == null;
}
}
#endregion
public DataGridViewRadioButtonCell()
{
base.ReadOnly = true;
}
#region 绘制
protected override void Paint(System.Drawing.Graphics graphics, System.Drawing.Rectangle clipBounds, System.Drawing.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, null, null, errorText, cellStyle, advancedBorderStyle, paintParts);
if (Display)
{
Point p = new Point();
Size s = RadioButtonRenderer.GetGlyphSize(graphics, System.Windows.Forms.VisualStyles.RadioButtonState.UncheckedNormal);
p.X = cellBounds.Location.X + (cellBounds.Width / 2) - (s.Width / 2);
p.Y = cellBounds.Location.Y + (cellBounds.Height / 2) - (s.Height / 2);
_cellLocation = cellBounds.Location;
radioButtonLocation = p;
radioButtonSize = s;
if (Checked)
{
if (Enabled)
{
_cbState = System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal;
}
else
{
_cbState = System.Windows.Forms.VisualStyles.RadioButtonState.CheckedDisabled;
}
}
else
{
if (Enabled)
{
_cbState = System.Windows.Forms.VisualStyles.RadioButtonState.UncheckedNormal;
}
else
{
_cbState = System.Windows.Forms.VisualStyles.RadioButtonState.UncheckedDisabled;
}
}
RadioButtonRenderer.DrawRadioButton(graphics, radioButtonLocation, _cbState);
}
}
protected override void OnMouseClick(DataGridViewCellMouseEventArgs e)
{
//可以编辑
if (!(IsReadOnly == DataGridViewTriState.True)
&& Display
&& Enabled)
{
Point p = new Point(e.X + _cellLocation.X, e.Y + _cellLocation.Y);
if (p.X >= radioButtonLocation.X
&& p.X <= radioButtonLocation.X + radioButtonSize.Width
&& p.Y >= radioButtonLocation.Y
&& p.Y <= radioButtonLocation.Y + radioButtonSize.Height)
{
Checked = !Checked;
if (OnRadioButtonClicked != null)
{
OnRadioButtonClicked(this, Checked);
}
this.DataGridView.InvalidateCell(this);
}
}
base.OnMouseClick(e);
}
protected override void OnKeyUp(KeyEventArgs e, int rowIndex)
{
base.OnKeyUp(e, rowIndex);
if (!(IsReadOnly == DataGridViewTriState.True)
&& Display
&& Enabled)
{
if (e.KeyCode == Keys.Space)
{
Checked = !Checked;
if (OnRadioButtonClicked != null)
{
OnRadioButtonClicked(this, Checked);
this.DataGridView.InvalidateCell(this);
}
}
}
}
#endregion
}
/// <summary>
/// 状态变化事件
/// </summary>
public delegate void RadioButtonClickedHandler(object sender, bool state);
public class DataGridViewRadioButtonCellEventArgs : EventArgs
{
bool _bChecked;
public DataGridViewRadioButtonCellEventArgs(bool bChecked)
{
_bChecked = bChecked;
}
public bool Checked
{
get { return _bChecked; }
}
}
/// <summary>
/// DataGridView单选列
/// </summary>
public class DataGridViewRadioButtonColumn : DataGridViewColumn
{
#region Property
private bool _isReadOnly = false;
/// <summary>
/// 是否只读
/// </summary>
[Category("行为")]
[Description("是否只读")]
[DefaultValue(false)]
[Browsable(true)]
[RefreshProperties(RefreshProperties.Repaint)]
public bool IsReadOnly
{
get { return _isReadOnly; }
set
{
_isReadOnly = value;
}
}
/// <summary>
/// 是否只读
/// </summary>
[Category("行为")]
[Description("是否只读")]
[DefaultValue(true)]
[Browsable(false)]
public new bool ReadOnly
{
get { return true; }
set
{
base.ReadOnly = true;
}
}
private bool _isSingleOn = true;
/// <summary>
/// 是否启用单行选中,单行模式,会自动控制其他行(不包括隐藏行)的选择
/// </summary>
[Category("行为")]
[Description("是否启用单行选中,单行模式,会自动控制其他行(不包括隐藏行)的选择")]
[DefaultValue(true)]
[Browsable(true)]
public bool SingleOn
{
get { return _isSingleOn; }
set
{
_isSingleOn = value;
}
}
#endregion
public DataGridViewRadioButtonColumn()
{
base.ReadOnly = true;
base.CellTemplate = new DataGridViewRadioButtonCell();
}
/// <summary>
/// 保证属性编辑器里修改的值能保存
/// </summary>
/// <returns></returns>
public override object Clone()
{
DataGridViewRadioButtonColumn col = (DataGridViewRadioButtonColumn)base.Clone();
col.IsReadOnly = IsReadOnly;
col.ReadOnly = true;
col.SingleOn = SingleOn;
return col;
}
}
}
var row = new DataGridViewRow();
var textBoxCell = new DataGridViewTextBoxCell();
var checkBoxCell = new DataGridViewRadioButtonCell();
checkBoxCell.Value = "False";
row.Cells.Add(checkBoxCell);
dgv.Rows.Add(row);