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 ()
159 SetState (row, GetState (null, row) & ~CheckState.Selected);
160 grid.Invalidate (grid.GetCurrentCellBounds ());
163 protected internal override void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string instantText, bool cellIsVisible)
166 oldState = GetState (source, rowNum);
167 SetState (rowNum, oldState | CheckState.Selected);
168 grid.Invalidate (grid.GetCurrentCellBounds ());
172 protected internal override void EnterNullValue ()
177 private bool ValueEquals (object value, object obj)
179 return value == null ? obj == null : value.Equals (obj);
182 protected internal override object GetColumnValueAtRow (CurrencyManager lm, int row)
184 object obj = base.GetColumnValueAtRow (lm, row);
186 if (ValueEquals (nullvalue, obj)) {
187 return Convert.DBNull;
190 if (ValueEquals (truevalue, obj)) {
197 protected internal override int GetMinimumHeight ()
199 return ThemeEngine.Current.DataGridMinimumColumnCheckBoxHeight;
202 protected internal override int GetPreferredHeight (Graphics g, object value)
204 return ThemeEngine.Current.DataGridMinimumColumnCheckBoxHeight;
207 protected internal override Size GetPreferredSize (Graphics g, object value)
209 return new Size (ThemeEngine.Current.DataGridMinimumColumnCheckBoxWidth, ThemeEngine.Current.DataGridMinimumColumnCheckBoxHeight);
212 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
214 Paint (g, bounds, source, rowNum, false);
217 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
219 Paint (g, bounds, source, rowNum, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
220 ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
223 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
225 Size chkbox_size = GetPreferredSize (g, null);
226 Rectangle rect = new Rectangle ();
228 CheckState check_state = GetState (source, rowNum);
230 chkbox_size.Width -= 2;
231 chkbox_size.Height -= 2;
233 rect.X = bounds.X + ((bounds.Width - chkbox_size.Width) / 2);
234 rect.Y = bounds.Y + ((bounds.Height - chkbox_size.Height) / 2);
235 rect.Width = chkbox_size.Width;
236 rect.Height = chkbox_size.Height;
238 // If the cell is selected
239 if ((check_state & CheckState.Selected) == CheckState.Selected) {
240 backBrush = ThemeEngine.Current.ResPool.GetSolidBrush (grid.SelectionBackColor);
241 check_state &= ~CheckState.Selected;
244 g.FillRectangle (backBrush, bounds);
246 switch (check_state) {
247 case CheckState.Checked:
248 state = ButtonState.Checked;
250 case CheckState.Null:
251 state = ButtonState.Checked | ButtonState.Inactive;
253 case CheckState.UnChecked:
255 state = ButtonState.Normal;
259 ThemeEngine.Current.CPDrawCheckBox (g, rect, state);
260 PaintGridLine (g, bounds);
263 protected internal override void SetColumnValueAtRow (CurrencyManager lm, int row, object obj)
267 if (ValueEquals (nullvalue, obj))
268 value = Convert.DBNull;
269 else if (ValueEquals (truevalue, obj))
271 else if (ValueEquals (falsevalue, obj))
275 base.SetColumnValueAtRow (lm, row, value);
277 #endregion // Public Instance Methods
279 #region Private Instance Methods
280 private object FromStateToValue (CheckState state)
282 if ((state & CheckState.Checked) == CheckState.Checked)
284 else if ((state & CheckState.Null) == CheckState.Null)
290 private CheckState FromValueToState (object obj)
292 if (ValueEquals (truevalue, obj))
293 return CheckState.Checked;
294 else if (ValueEquals (nullvalue, obj))
295 return CheckState.Null;
297 return CheckState.UnChecked;
300 private CheckState GetState (CurrencyManager source, int row)
304 if (checkboxes_state[row] == null) {
305 object value = GetColumnValueAtRow (source, row);
306 state = FromValueToState (value);
307 checkboxes_state.Add (row, state);
309 state = (CheckState) checkboxes_state[row];
315 private CheckState GetNextState (CheckState state)
317 CheckState new_state;
318 bool selected = ((state & CheckState.Selected) == CheckState.Selected);
320 switch (state & ~CheckState.Selected) {
321 case CheckState.Checked:
322 new_state = CheckState.Null;
324 case CheckState.Null:
325 new_state = CheckState.UnChecked;
327 case CheckState.UnChecked:
329 new_state = CheckState.Checked;
334 new_state = new_state | CheckState.Selected;
340 internal override void OnKeyDown (KeyEventArgs ke, int row, int column)
342 switch (ke.KeyCode) {
344 NextState (row, column);
349 internal override void OnMouseDown (MouseEventArgs e, int row, int column)
352 NextState (row, column);
355 private void NextState (int row, int column)
357 grid.ColumnStartedEditing (new Rectangle());
359 SetState (row, GetNextState (GetState (null, row)));
361 grid.Invalidate (grid.GetCellBounds (row, column));
364 private void SetState (int row, CheckState state)
366 checkboxes_state[row] = state;
369 #endregion Private Instance Methods
372 public event EventHandler AllowNullChanged;
373 public event EventHandler FalseValueChanged;
374 public event EventHandler TrueValueChanged;