2013-09-27 168 views
0

从这个link开始我做了一个单选按钮类型(列和单元格)的自定义DataGridViewColumn。c#:DataGridView自定义单元格丢失自定义属性

public class DataGridViewRadioButtonColumnEx : DataGridViewColumn 
{ 
    public DataGridViewRadioButtonColumnEx() 
    { 
     this.CellTemplate = new DataGridViewRadioButtonCell(); 
     this.ReadOnly = true; 
    } 
} 

public delegate void RadioButtonClickedHandler(bool state); 
public class DataGridViewRadioButtonCellEventArgs : EventArgs 
{ 
    bool _bChecked; 
    public DataGridViewRadioButtonCellEventArgs(bool bChecked) 
    { 
     _bChecked = bChecked; 
    } 

    public bool Checked 
    { 
     get { return _bChecked; } 
    } 
} 

public class DataGridViewRadioButtonCell : DataGridViewTextBoxCell 
{ 
    Point radioButtonLocation; 
    Size radioButtonSize; 
    bool _checked = false; 
    public bool Checked 
    { 
     get { return _checked; } 
     set { _checked = value; } 
    } 

    string _groupName = ""; 
    public string GroupName 
    { 
     get 
     { 
      return _groupName; 
     } 
     set 
     { 
      _groupName = value; 
     } 
    } 

    Point _cellLocation = new Point(); 
    System.Windows.Forms.VisualStyles.RadioButtonState _cbState = System.Windows.Forms.VisualStyles.RadioButtonState.UncheckedNormal; 
    public event RadioButtonClickedHandler OnRadioButtonClicked; 

    public DataGridViewRadioButtonCell() 
    { 
    } 

    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, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts); 

     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) 
      _cbState = System.Windows.Forms.VisualStyles.RadioButtonState.CheckedNormal; 
     else 
      _cbState = System.Windows.Forms.VisualStyles.RadioButtonState.UncheckedNormal; 

     RadioButtonRenderer.DrawRadioButton(graphics, radioButtonLocation, _cbState); 
    } 

    protected override void OnMouseClick(DataGridViewCellMouseEventArgs e) 
    { 
     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(_checked); 
       this.DataGridView.InvalidateCell(this); 
      } 
     } 
     base.OnMouseClick(e); 
    } 

    protected override void OnKeyUp(KeyEventArgs e, int rowIndex) 
    { 
     base.OnKeyUp(e, rowIndex); 
     if (e.KeyCode == Keys.Space) 
     { 
      _checked = true; 

      if (OnRadioButtonClicked != null) 
      { 
       OnRadioButtonClicked(_checked); 
       this.DataGridView.InvalidateCell(this); 
      } 
     } 
    } 

    /// <summary> 
    /// To Set the status of the Check-Box Header column 
    /// </summary> 
    /// <param name="flagIndicator">True - to mark checked state. False : To mark it as Unchecked.</param> 
    public void SetRadioButton(bool flagIndicator) 
    { 
     _checked = flagIndicator; 

     this.DataGridView.InvalidateCell(this); 
    } 
} 

它做工精细,我添加了名为“组名”自定义属性(用于现在的组单选按钮属于),但在运行时,某个地方,将被清除。

public class CustomDataGridView : DataGridView 
{ 
    protected override void OnCellClick(DataGridViewCellEventArgs e) 
    { 
     if ((e.RowIndex > -1) && (e.ColumnIndex > -1)) 
     { 
      if ((this[e.ColumnIndex, e.RowIndex]).OwningColumn is DataGridViewRadioButtonColumnEx) 
      { 
       DataGridViewRadioButtonCell cell = this[e.ColumnIndex, e.RowIndex] as DataGridViewRadioButtonCell; 
       cell.Checked = !cell.Checked; 
       if (((DataGridViewRadioButtonCell)cell).Checked) 
       { 
        for (int i = 0; i < this.RowCount; i++) 
        { 
         if (cell.GroupName == (this[e.ColumnIndex, i] as DataGridViewRadioButtonCell).GroupName) 
          (this[e.ColumnIndex, i] as DataGridViewRadioButtonCell).Checked = false; 
        } 
       } 
      } 
     } 
     base.OnCellClick(e); 
     this.InvalidateColumn(e.ColumnIndex); 
    } 
} 

如何检测属性GroupName的清除位置?

谢谢。 Kendo

LE: 我发现它!我必须覆盖clone方法:

public override object Clone() 
    { 
     var clone = (DataGridViewRadioButtonCell)base.Clone(); 

     clone.Checked = _checked; 
     clone.GroupName = _groupName; 
     clone.CellType = _cellType; 

     return clone; 
    } 

回答

0

在Visual Studio:你的财产的occurence 右击 - >查找所有引用。 或者,您可以在设置器GroupName中放置一个断点,并观察在调试期间改变它的任何调用。

+0

谢谢你,我已经完成了所有这些事情:) – Kendo

+0

好吧,从你的例子中很难分辨出来,因为Setter从来没有被访问过。你确定它首先被设置? – nuke

+0

Setter只有在初始化时才被访问。 'row.Cells.Add(new DataGridViewRadioButtonCell(){GroupName =“g1”});' – Kendo