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>
27 using System.ComponentModel;
29 using System.Globalization;
30 using System.Runtime.InteropServices;
31 using System.Diagnostics;
33 namespace System.Windows.Forms
35 public class DataGridTextBoxColumn : DataGridColumnStyle
37 #region Local Variables
38 private string format;
39 private IFormatProvider format_provider = null;
40 private StringFormat string_format = new StringFormat ();
41 private DataGridTextBox textbox;
42 private static readonly int offset_x = 2;
43 private static readonly int offset_y = 2;
44 #endregion // Local Variables
47 public DataGridTextBoxColumn () : this (null, String.Empty, false)
51 public DataGridTextBoxColumn (PropertyDescriptor prop) : this (prop, String.Empty, false)
55 public DataGridTextBoxColumn (PropertyDescriptor prop, bool isDefault) : this (prop, String.Empty, isDefault)
59 public DataGridTextBoxColumn (PropertyDescriptor prop, string format) : this (prop, format, false)
63 public DataGridTextBoxColumn (PropertyDescriptor prop, string format, bool isDefault) : base (prop)
66 is_default = isDefault;
68 textbox = new DataGridTextBox ();
69 textbox.Multiline = true;
70 textbox.WordWrap = false;
71 textbox.BorderStyle = BorderStyle.None;
72 textbox.Visible = false;
77 #region Public Instance Properties
78 [Editor("System.Windows.Forms.Design.DataGridColumnStyleFormatEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
82 public string Format {
83 get { return format; }
85 if (value != format) {
93 [EditorBrowsable(EditorBrowsableState.Advanced)]
94 public IFormatProvider FormatInfo {
95 get { return format_provider; }
97 if (value != format_provider) {
98 format_provider = value;
104 public override PropertyDescriptor PropertyDescriptor {
105 set { base.PropertyDescriptor = value; }
108 public override bool ReadOnly {
109 get { return base.ReadOnly; }
110 set { base.ReadOnly = value; }
114 public virtual TextBox TextBox {
115 get { return textbox; }
117 #endregion // Public Instance Properties
119 #region Public Instance Methods
121 protected internal override void Abort (int rowNum)
126 protected internal override bool Commit (CurrencyManager dataSource, int rowNum)
128 textbox.Bounds = Rectangle.Empty;
130 /* Do not write data if not editing. */
131 if (textbox.IsInEditOrNavigateMode)
135 string existing_text = GetFormattedValue (dataSource, rowNum);
137 if (existing_text != textbox.Text) {
138 if (textbox.Text == NullText) {
139 SetColumnValueAtRow (dataSource, rowNum, DBNull.Value);
141 object newValue = textbox.Text;
143 TypeConverter converter = TypeDescriptor.GetConverter (
144 PropertyDescriptor.PropertyType);
145 if (converter != null && converter.CanConvertFrom (typeof (string))) {
146 newValue = converter.ConvertFrom (null, CultureInfo.CurrentCulture,
148 if (converter.CanConvertTo (typeof (string)))
149 textbox.Text = (string) converter.ConvertTo (null,
150 CultureInfo.CurrentCulture, newValue, typeof (string));
153 SetColumnValueAtRow (dataSource, rowNum, newValue);
165 protected internal override void ConcedeFocus ()
170 protected internal override void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible)
172 grid.SuspendLayout ();
174 textbox.TextChanged -= new EventHandler (textbox_TextChanged);
176 textbox.TextAlign = alignment;
180 ro = (TableStyleReadOnly || ReadOnly || readOnly);
182 if (!ro && displayText != null) {
183 textbox.Text = displayText;
184 textbox.IsInEditOrNavigateMode = false;
186 textbox.Text = GetFormattedValue (source, rowNum);
189 textbox.TextChanged += new EventHandler (textbox_TextChanged);
191 textbox.ReadOnly = ro;
192 textbox.Bounds = new Rectangle (new Point (bounds.X + offset_x, bounds.Y + offset_y),
193 new Size (bounds.Width - offset_x, bounds.Height - offset_y));
194 textbox.Visible = cellIsVisible;
195 textbox.SelectAll ();
197 grid.ResumeLayout (false);
201 void textbox_TextChanged (object o, EventArgs e)
203 textbox.IsInEditOrNavigateMode = false;
206 protected void EndEdit ()
208 textbox.TextChanged -= new EventHandler (textbox_TextChanged);
212 protected internal override void EnterNullValue ()
214 textbox.Text = NullText;
217 protected internal override int GetMinimumHeight ()
219 return FontHeight + 3;
222 protected internal override int GetPreferredHeight (Graphics g, object value)
224 string text = GetFormattedValue (value);
225 System.Text.RegularExpressions.Regex r = new System.Text.RegularExpressions.Regex("/\r\n/");
226 int lines = r.Matches (text).Count;
227 return this.DataGridTableStyle.DataGrid.Font.Height * (lines+1) + 1;
230 protected internal override Size GetPreferredSize (Graphics g, object value)
232 string text = GetFormattedValue (value);
233 Size s = Size.Ceiling (g.MeasureString (text, this.DataGridTableStyle.DataGrid.Font));
239 protected void HideEditBox ()
241 if (!textbox.Visible)
244 grid.SuspendLayout ();
245 textbox.Bounds = Rectangle.Empty;
246 textbox.Visible = false;
247 textbox.IsInEditOrNavigateMode = true;
248 grid.ResumeLayout (false);
251 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
253 Paint (g, bounds, source, rowNum, false);
256 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
258 Paint (g, bounds, source, rowNum, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
259 ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
262 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
264 PaintText (g, bounds, GetFormattedValue (source, rowNum), backBrush, foreBrush, alignToRight);
267 protected void PaintText (Graphics g, Rectangle bounds, string text, bool alignToRight)
269 PaintText (g, bounds, text, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
270 ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
273 protected void PaintText (Graphics g, Rectangle textBounds, string text, Brush backBrush, Brush foreBrush, bool alignToRight)
275 if (alignToRight == true) {
276 string_format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
278 string_format.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
282 case HorizontalAlignment.Center:
283 string_format.Alignment = StringAlignment.Center;
285 case HorizontalAlignment.Right:
286 string_format.Alignment = StringAlignment.Far;
289 string_format.Alignment = StringAlignment.Near;
293 g.FillRectangle (backBrush, textBounds);
294 PaintGridLine (g, textBounds);
296 textBounds.X += offset_x;
297 textBounds.Width -= offset_x;
299 textBounds.Y += offset_y;
300 textBounds.Height -= offset_y;
302 string_format.FormatFlags |= StringFormatFlags.NoWrap;
303 g.DrawString (text, DataGridTableStyle.DataGrid.Font, foreBrush, textBounds, string_format);
307 protected internal override void ReleaseHostedControl ()
312 grid.SuspendLayout ();
313 grid.Controls.Remove (textbox);
314 grid.Invalidate (new Rectangle (textbox.Location, textbox.Size));
317 grid.ResumeLayout (false);
320 protected override void SetDataGridInColumn (DataGrid value)
322 base.SetDataGridInColumn (value);
327 textbox.SetDataGrid (grid);
328 grid.SuspendLayout ();
329 grid.Controls.Add (textbox);
330 grid.ResumeLayout (false);
333 protected internal override void UpdateUI (CurrencyManager source, int rowNum, string displayText)
335 if (textbox.Visible // I don't really like this, but it gets DataGridTextBoxColumnTest.TestUpdateUI passing
336 && textbox.IsInEditOrNavigateMode) {
337 textbox.Text = GetFormattedValue (source, rowNum);
339 textbox.Text = displayText;
343 #endregion // Public Instance Methods
345 #region Private Instance Methods
347 private string GetFormattedValue (CurrencyManager source, int rowNum)
349 object obj = GetColumnValueAtRow (source, rowNum);
350 return GetFormattedValue (obj);
353 private string GetFormattedValue (object obj)
355 if (DBNull.Value.Equals(obj) || obj == null)
358 if (format != null && format != String.Empty && obj as IFormattable != null)
359 return ((IFormattable) obj).ToString (format, format_provider);
361 TypeConverter converter = TypeDescriptor.GetConverter (
362 PropertyDescriptor.PropertyType);
363 if (converter != null && converter.CanConvertTo (typeof (string)))
364 return (string) converter.ConvertTo (null, CultureInfo.CurrentCulture,
365 obj, typeof (string));
367 return obj.ToString ();
370 #endregion Private Instance Methods