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 // Jordi Mas i Hernandez <jordi@ximian.com>
29 using System.ComponentModel;
31 using System.Runtime.InteropServices;
32 using System.Diagnostics;
33 using System.Collections;
35 namespace System.Windows.Forms
37 public class DataGridBoolColumn : DataGridColumnStyle
40 private enum CheckState {
42 UnChecked = 0x00000002,
47 #region Local Variables
48 private bool allownull;
49 private object falsevalue;
50 private object nullvalue;
51 private object truevalue;
52 private Hashtable checkboxes_state;
56 #endregion // Local Variables
59 public DataGridBoolColumn () : this (null, false)
63 public DataGridBoolColumn (PropertyDescriptor prop) : this (prop, false)
67 public DataGridBoolColumn (PropertyDescriptor prop, bool isDefault) : base (prop)
73 checkboxes_state = new Hashtable ();
74 is_default = isDefault;
78 #region Public Instance Properties
80 public bool AllowNull {
85 if (value != allownull) {
88 if (AllowNullChanged != null) {
89 AllowNullChanged (this, EventArgs.Empty);
95 [TypeConverter(typeof(System.ComponentModel.StringConverter))]
96 public object FalseValue {
101 if (value != falsevalue) {
104 if (FalseValueChanged != null) {
105 FalseValueChanged (this, EventArgs.Empty);
111 [TypeConverter(typeof(System.ComponentModel.StringConverter))]
112 public object NullValue {
117 if (value != nullvalue) {
123 [TypeConverter(typeof(System.ComponentModel.StringConverter))]
124 public object TrueValue {
129 if (value != truevalue) {
132 if (TrueValueChanged != null) {
133 TrueValueChanged (this, EventArgs.Empty);
138 #endregion // Public Instance Properties
140 #region Public Instance Methods
141 protected internal override void Abort (int rowNum)
143 SetState (rowNum, oldState & ~CheckState.Selected);
144 grid.Invalidate (grid.GetCurrentCellBounds ());
147 protected internal override bool Commit (CurrencyManager source, int rowNum)
149 CheckState newState = GetState (source, rowNum);
150 SetColumnValueAtRow (source, rowNum, FromStateToValue (newState));
151 SetState (rowNum, newState & ~CheckState.Selected);
152 grid.Invalidate (grid.GetCurrentCellBounds ());
157 protected internal override void ConcedeFocus ()
161 protected internal override void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
164 oldState = GetState (source, rowNum);
165 SetState (rowNum, oldState | CheckState.Selected);
166 grid.Invalidate (grid.GetCurrentCellBounds ());
170 protected internal override void EnterNullValue ()
175 private bool ValueEquals (object value, object obj)
177 return value == null ? obj == null : value.Equals (obj);
180 protected internal override object GetColumnValueAtRow (CurrencyManager lm, int row)
182 object obj = base.GetColumnValueAtRow (lm, row);
184 if (ValueEquals (nullvalue, obj)) {
185 return Convert.DBNull;
188 if (ValueEquals (truevalue, obj)) {
195 protected internal override int GetMinimumHeight ()
197 return ThemeEngine.Current.DataGridMinimumColumnCheckBoxHeight;
200 protected internal override int GetPreferredHeight (Graphics g, object value)
202 return ThemeEngine.Current.DataGridMinimumColumnCheckBoxHeight;
205 protected internal override Size GetPreferredSize (Graphics g, object value)
207 return new Size (ThemeEngine.Current.DataGridMinimumColumnCheckBoxWidth, ThemeEngine.Current.DataGridMinimumColumnCheckBoxHeight);
210 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
212 Paint (g, bounds, source, rowNum, false);
215 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
217 Paint (g, bounds, source, rowNum, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
218 ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
221 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
223 Size chkbox_size = GetPreferredSize (g, null);
224 Rectangle rect = new Rectangle ();
226 CheckState check_state = GetState (source, rowNum);
228 chkbox_size.Width -= 2;
229 chkbox_size.Height -= 2;
231 rect.X = bounds.X + ((bounds.Width - chkbox_size.Width) / 2);
232 rect.Y = bounds.Y + ((bounds.Height - chkbox_size.Height) / 2);
233 rect.Width = chkbox_size.Width;
234 rect.Height = chkbox_size.Height;
236 // If the cell is selected
237 if ((check_state & CheckState.Selected) == CheckState.Selected) {
238 backBrush = ThemeEngine.Current.ResPool.GetSolidBrush (grid.SelectionBackColor);
239 check_state &= ~CheckState.Selected;
242 g.FillRectangle (backBrush, bounds);
244 switch (check_state) {
245 case CheckState.Checked:
246 state = ButtonState.Checked;
248 case CheckState.Null:
249 state = ButtonState.Checked | ButtonState.Inactive;
251 case CheckState.UnChecked:
253 state = ButtonState.Normal;
257 ThemeEngine.Current.CPDrawCheckBox (g, rect, state);
258 PaintGridLine (g, bounds);
261 protected internal override void SetColumnValueAtRow (CurrencyManager lm, int row, object obj)
265 if (ValueEquals (nullvalue, obj))
266 value = Convert.DBNull;
267 else if (ValueEquals (truevalue, obj))
269 else if (ValueEquals (falsevalue, obj))
273 base.SetColumnValueAtRow (lm, row, value);
275 #endregion // Public Instance Methods
277 #region Private Instance Methods
278 private object FromStateToValue (CheckState state)
280 if ((state & CheckState.Checked) == CheckState.Checked)
282 else if ((state & CheckState.Null) == CheckState.Null)
288 private CheckState FromValueToState (object obj)
290 if (ValueEquals (truevalue, obj))
291 return CheckState.Checked;
292 else if (ValueEquals (nullvalue, obj))
293 return CheckState.Null;
295 return CheckState.UnChecked;
298 private CheckState GetState (CurrencyManager source, int row)
302 if (checkboxes_state[row] == null) {
303 object value = GetColumnValueAtRow (source, row);
304 state = FromValueToState (value);
305 checkboxes_state.Add (row, state);
307 state = (CheckState) checkboxes_state[row];
313 private CheckState GetNextState (CheckState state)
315 CheckState new_state;
316 bool selected = ((state & CheckState.Selected) == CheckState.Selected);
318 switch (state & ~CheckState.Selected) {
319 case CheckState.Checked:
320 new_state = CheckState.Null;
322 case CheckState.Null:
323 new_state = CheckState.UnChecked;
325 case CheckState.UnChecked:
327 new_state = CheckState.Checked;
332 new_state = new_state | CheckState.Selected;
338 internal override void OnKeyDown (KeyEventArgs ke, int row, int column)
340 switch (ke.KeyCode) {
342 NextState (row, column);
347 internal override void OnMouseDown (MouseEventArgs e, int row, int column)
350 NextState (row, column);
353 private void NextState (int row, int column)
355 grid.ColumnStartedEditing (new Rectangle());
357 SetState (row, GetNextState (GetState (null, row)));
359 grid.Invalidate (grid.GetCellBounds (row, column));
362 private void SetState (int row, CheckState state)
364 checkboxes_state[row] = state;
367 #endregion Private Instance Methods
370 public event EventHandler AllowNullChanged;
371 public event EventHandler FalseValueChanged;
372 public event EventHandler TrueValueChanged;