1 // Permission is hereby granted, free of charge, to any person obtaining
2 // a copy of this software and associated documentation files (the
3 // "Software"), to deal in the Software without restriction, including
4 // without limitation the rights to use, copy, modify, merge, publish,
5 // distribute, sublicense, and/or sell copies of the Software, and to
6 // permit persons to whom the Software is furnished to do so, subject to
7 // the following conditions:
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
12 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
13 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
14 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
15 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
16 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
17 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
18 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
23 // Pedro MartÃnez Juliá <pedromj@gmail.com>
30 using System.ComponentModel;
32 using System.Windows.Forms.VisualStyles;
34 namespace System.Windows.Forms {
36 public class DataGridViewCheckBoxCell : DataGridViewCell, IDataGridViewEditingCell {
38 private object editingCellFormattedValue;
39 private bool editingCellValueChanged;
40 private object falseValue;
41 private FlatStyle flatStyle;
42 private object indeterminateValue;
43 private bool threeState;
44 private object trueValue;
45 private Type valueType;
46 private PushButtonState check_state;
48 public DataGridViewCheckBoxCell ()
50 check_state = PushButtonState.Normal;
51 editingCellValueChanged = false;
53 flatStyle = FlatStyle.Standard;
54 indeterminateValue = null;
60 public DataGridViewCheckBoxCell (bool threeState) : this()
62 this.threeState = threeState;
65 public virtual object EditingCellFormattedValue {
66 get { return editingCellFormattedValue; }
68 if (FormattedValueType == null || value == null || value.GetType() != FormattedValueType || !(value is Boolean) || !(value is CheckState)) {
69 throw new ArgumentException("Cannot set this property.");
71 editingCellFormattedValue = value;
75 public virtual bool EditingCellValueChanged {
76 get { return editingCellValueChanged; }
77 set { editingCellValueChanged = value; }
80 public override Type EditType {
85 public object FalseValue {
86 get { return falseValue; }
87 set { falseValue = value; }
90 [DefaultValue (FlatStyle.Standard)]
91 public FlatStyle FlatStyle {
92 get { return flatStyle; }
94 if (!Enum.IsDefined(typeof(FlatStyle), value)) {
95 throw new InvalidEnumArgumentException("Value is not valid FlatStyle.");
97 if (value == FlatStyle.Popup) {
98 throw new Exception("FlatStyle cannot be set to Popup in this control.");
103 public override Type FormattedValueType {
106 return typeof(CheckState);
108 return typeof(Boolean);
112 [DefaultValue (null)]
113 public object IndeterminateValue {
114 get { return indeterminateValue; }
115 set { indeterminateValue = value; }
118 [DefaultValue (false)]
119 public bool ThreeState {
120 get { return threeState; }
121 set { threeState = value; }
124 [DefaultValue (null)]
125 public object TrueValue {
126 get { return trueValue; }
127 set { trueValue = value; }
130 public override Type ValueType {
132 if (valueType == null) {
133 if (OwningColumn != null && OwningColumn.ValueType != null) {
134 return OwningColumn.ValueType;
137 return typeof(CheckState);
139 return typeof(Boolean);
143 set { valueType = value; }
146 public override object Clone ()
148 DataGridViewCheckBoxCell cell = (DataGridViewCheckBoxCell) base.Clone();
149 cell.editingCellValueChanged = this.editingCellValueChanged;
150 cell.falseValue = this.falseValue;
151 cell.flatStyle = this.flatStyle;
152 cell.indeterminateValue = this.indeterminateValue;
153 cell.threeState = this.threeState;
154 cell.trueValue = this.trueValue;
155 cell.valueType = this.valueType;
159 public virtual object GetEditingCellFormattedValue (DataGridViewDataErrorContexts context)
161 if (FormattedValueType == null) {
162 throw new InvalidOperationException("FormattedValueType is null.");
164 if ((context & DataGridViewDataErrorContexts.ClipboardContent) != 0) {
165 return Convert.ToString(Value);
168 return (CheckState) Value;
170 return (Boolean) Value;
173 public override object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
175 if (cellStyle == null) {
176 throw new ArgumentNullException("CellStyle is null");
178 if (FormattedValueType == null) {
179 throw new FormatException("FormattedValueType is null.");
181 if (formattedValue == null || formattedValue.GetType() != FormattedValueType) {
182 throw new ArgumentException("FormattedValue is null or is not instance of FormattedValueType.");
185 return base.ParseFormattedValue (formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
188 public virtual void PrepareEditingCellForEdit (bool selectAll)
192 public override string ToString ()
194 return string.Format ("DataGridViewCheckBoxCell {{ ColumnIndex={0}, RowIndex={1} }}", ColumnIndex, RowIndex);
197 protected override bool ContentClickUnsharesRow (DataGridViewCellEventArgs e)
199 return this.IsInEditMode;
202 protected override bool ContentDoubleClickUnsharesRow (DataGridViewCellEventArgs e)
204 return this.IsInEditMode;
207 protected override AccessibleObject CreateAccessibilityInstance ()
209 return new DataGridViewCheckBoxCellAccessibleObject(this);
212 protected override Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
214 if (DataGridView == null)
215 return Rectangle.Empty;
217 return new Rectangle ((Size.Width - 13) / 2, (Size.Height - 13) / 2, 13, 13);
221 protected override Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
223 return Rectangle.Empty;
226 protected override object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
228 if (DataGridView == null)
231 if (value == falseValue)
233 if (value == trueValue)
236 return Convert.ToBoolean (value);
239 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
241 return new Size (21, 20);
244 protected override bool KeyDownUnsharesRow (KeyEventArgs e, int rowIndex)
246 // true if the user pressed the SPACE key without modifier keys; otherwise, false
247 return e.KeyData == Keys.Space;
250 protected override bool KeyUpUnsharesRow (KeyEventArgs e, int rowIndex)
252 // true if the user released the SPACE key; otherwise false
253 return e.KeyData == Keys.Space;
256 protected override bool MouseDownUnsharesRow (DataGridViewCellMouseEventArgs e)
258 return (e.Button == MouseButtons.Left);
261 protected override bool MouseEnterUnsharesRow (int rowIndex)
263 // true if the cell was the last cell receiving a mouse click; otherwise, false.
267 protected override bool MouseLeaveUnsharesRow (int rowIndex)
269 // true if the button displayed by the cell is in the pressed state; otherwise, false.
270 return check_state == PushButtonState.Pressed;
273 protected override bool MouseUpUnsharesRow (DataGridViewCellMouseEventArgs e)
275 // true if the mouse up was caused by the release of the left mouse button; otherwise false.
276 return e.Button == MouseButtons.Left;
279 protected override void OnContentClick (DataGridViewCellEventArgs e)
281 DataGridViewCellStyle current_style = InheritedStyle;
283 bool current = (bool)GetFormattedValue (Value, e.RowIndex, ref current_style, null, null, DataGridViewDataErrorContexts.Parsing);
286 Value = falseValue == null ? false : falseValue;
288 Value = trueValue == null ? true : trueValue;
291 protected override void OnContentDoubleClick (DataGridViewCellEventArgs e)
295 protected override void OnKeyDown (KeyEventArgs e, int rowIndex)
297 // when activated by the SPACE key, this method updates the cell's user interface
298 if ((e.KeyData & Keys.Space) == Keys.Space) {
299 check_state = PushButtonState.Pressed;
300 DataGridView.InvalidateCell (this);
304 protected override void OnKeyUp (KeyEventArgs e, int rowIndex)
306 // when activated by the SPACE key, this method updates the cell's user interface
307 if ((e.KeyData & Keys.Space) == Keys.Space) {
308 check_state = PushButtonState.Normal;
309 DataGridView.InvalidateCell (this);
313 protected override void OnLeave (int rowIndex, bool throughMouseClick)
315 if (check_state != PushButtonState.Normal) {
316 check_state = PushButtonState.Normal;
317 DataGridView.InvalidateCell (this);
321 protected override void OnMouseDown (DataGridViewCellMouseEventArgs e)
323 // if activated by depresing the left mouse button, this method updates the cell's user interface
324 if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
325 check_state = PushButtonState.Pressed;
326 DataGridView.InvalidateCell (this);
330 protected override void OnMouseLeave (int rowIndex)
332 // if the cell's button is not in its normal state, this method causes the cell's user interface to be updated.
333 if (check_state != PushButtonState.Normal) {
334 check_state = PushButtonState.Normal;
335 DataGridView.InvalidateCell (this);
339 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e)
341 if (check_state != PushButtonState.Normal && check_state != PushButtonState.Hot) {
342 check_state = PushButtonState.Hot;
343 DataGridView.InvalidateCell (this);
347 protected override void OnMouseUp (DataGridViewCellMouseEventArgs e)
349 // if activated by the left mouse button, this method updates the cell's user interface
350 if ((e.Button & MouseButtons.Left) == MouseButtons.Left) {
351 check_state = PushButtonState.Normal;
352 DataGridView.InvalidateCell (this);
356 protected override void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
358 base.Paint (graphics, clipBounds, cellBounds, rowIndex, cellState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
361 internal override void PaintPartContent (Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, object formattedValue)
365 if ((bool)formattedValue == false)
366 state = (CheckBoxState)check_state;
367 else if ((bool)formattedValue == true)
368 state = (CheckBoxState)((int)check_state + 4);
370 state = (CheckBoxState)((int)check_state + 8);
372 Point p = new Point (cellBounds.X + (Size.Width - 13) / 2, cellBounds.Y + (Size.Height - 13) / 2);
373 CheckBoxRenderer.DrawCheckBox (graphics, p, state);
376 protected class DataGridViewCheckBoxCellAccessibleObject : DataGridViewCellAccessibleObject {
378 public DataGridViewCheckBoxCellAccessibleObject (DataGridViewCell owner) : base(owner)
382 public override string DefaultAction {
384 if (Owner.ReadOnly) {
387 // return "Press to check" if the check box is not selected
388 // and "Press to uncheck" if the check box is selected
389 throw new NotImplementedException();
393 public override void DoDefaultAction ()
395 // change the state of the check box
398 public override int GetChildCount ()