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;
55 #endregion // Local Variables
58 public DataGridBoolColumn () : this (null, false)
62 public DataGridBoolColumn (PropertyDescriptor prop) : this (prop, false)
66 public DataGridBoolColumn (PropertyDescriptor prop, bool isDefault) : base (prop)
72 checkboxes_state = new Hashtable ();
73 is_default = isDefault;
77 #region Public Instance Properties
79 public bool AllowNull {
84 if (value != allownull) {
87 EventHandler eh = (EventHandler)(Events [AllowNullChangedEvent]);
89 eh (this, EventArgs.Empty);
94 [TypeConverter(typeof(System.ComponentModel.StringConverter))]
95 public object FalseValue {
100 if (value != falsevalue) {
103 EventHandler eh = (EventHandler)(Events [FalseValueChangedEvent]);
105 eh (this, EventArgs.Empty);
110 [TypeConverter(typeof(System.ComponentModel.StringConverter))]
111 public object NullValue {
116 if (value != nullvalue) {
119 // XXX no NullValueChangedEvent? lame.
124 [TypeConverter(typeof(System.ComponentModel.StringConverter))]
125 public object TrueValue {
130 if (value != truevalue) {
133 EventHandler eh = (EventHandler)(Events [TrueValueChangedEvent]);
135 eh (this, EventArgs.Empty);
139 #endregion // Public Instance Properties
141 #region Public Instance Methods
142 protected internal override void Abort (int rowNum)
144 SetState (rowNum, oldState & ~CheckState.Selected);
145 grid.Invalidate (grid.GetCurrentCellBounds ());
148 protected internal override bool Commit (CurrencyManager source, int rowNum)
150 CheckState newState = GetState (source, rowNum);
151 SetColumnValueAtRow (source, rowNum, FromStateToValue (newState));
152 SetState (rowNum, newState & ~CheckState.Selected);
153 grid.Invalidate (grid.GetCurrentCellBounds ());
158 protected internal override void ConcedeFocus ()
162 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)
349 NextState (row, column);
352 private void NextState (int row, int column)
354 grid.ColumnStartedEditing (new Rectangle());
356 SetState (row, GetNextState (GetState (null, row)));
358 grid.Invalidate (grid.GetCellBounds (row, column));
361 private void SetState (int row, CheckState state)
363 checkboxes_state[row] = state;
366 #endregion Private Instance Methods
369 static object AllowNullChangedEvent = new object ();
370 static object FalseValueChangedEvent = new object ();
371 static object TrueValueChangedEvent = new object ();
373 public event EventHandler AllowNullChanged {
374 add { Events.AddHandler (AllowNullChangedEvent, value); }
375 remove { Events.RemoveHandler (AllowNullChangedEvent, value); }
378 public event EventHandler FalseValueChanged {
379 add { Events.AddHandler (FalseValueChangedEvent, value); }
380 remove { Events.RemoveHandler (FalseValueChangedEvent, value); }
383 public event EventHandler TrueValueChanged {
384 add { Events.AddHandler (TrueValueChangedEvent, value); }
385 remove { Events.RemoveHandler (TrueValueChangedEvent, value); }