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))]
80 public string Format {
81 get { return format; }
83 if (value != format) {
91 [EditorBrowsable(EditorBrowsableState.Advanced)]
92 public IFormatProvider FormatInfo {
93 get { return format_provider; }
95 if (value != format_provider) {
96 format_provider = value;
102 public override PropertyDescriptor PropertyDescriptor {
103 set { base.PropertyDescriptor = value; }
106 public override bool ReadOnly {
107 get { return base.ReadOnly; }
108 set { base.ReadOnly = value; }
112 public virtual TextBox TextBox {
113 get { return textbox; }
115 #endregion // Public Instance Properties
117 #region Public Instance Methods
119 protected internal override void Abort (int rowNum)
124 protected internal override bool Commit (CurrencyManager dataSource, int rowNum)
126 textbox.Bounds = Rectangle.Empty;
128 /* Do not write data if not editing. */
129 if (textbox.IsInEditOrNavigateMode)
133 string existing_text = GetFormattedValue (dataSource, rowNum);
135 if (existing_text != textbox.Text) {
136 if (textbox.Text == NullText) {
137 SetColumnValueAtRow (dataSource, rowNum, DBNull.Value);
139 object newValue = textbox.Text;
141 TypeConverter converter = TypeDescriptor.GetConverter (
142 PropertyDescriptor.PropertyType);
143 if (converter != null && converter.CanConvertFrom (typeof (string))) {
144 newValue = converter.ConvertFrom (null, CultureInfo.CurrentCulture,
146 if (converter.CanConvertTo (typeof (string)))
147 textbox.Text = (string) converter.ConvertTo (null,
148 CultureInfo.CurrentCulture, newValue, typeof (string));
151 SetColumnValueAtRow (dataSource, rowNum, newValue);
162 protected internal override void ConcedeFocus ()
167 protected internal override void Edit (CurrencyManager source, int rowNum, Rectangle bounds, bool readOnly, string displayText, bool cellIsVisible)
169 string instantText = displayText;
170 grid.SuspendLayout ();
172 textbox.TextChanged -= new EventHandler (textbox_TextChanged);
174 textbox.TextAlign = alignment;
178 ro = (TableStyleReadOnly || ReadOnly || readOnly);
180 if (!ro && instantText != null) {
181 textbox.Text = instantText;
182 textbox.IsInEditOrNavigateMode = false;
184 textbox.Text = GetFormattedValue (source, rowNum);
187 textbox.TextChanged += new EventHandler (textbox_TextChanged);
189 textbox.ReadOnly = ro;
190 textbox.Bounds = new Rectangle (new Point (bounds.X + offset_x, bounds.Y + offset_y),
191 new Size (bounds.Width - offset_x - 1, bounds.Height - offset_y - 1));
193 textbox.Visible = cellIsVisible;
194 textbox.SelectAll ();
196 grid.ResumeLayout (false);
200 void textbox_TextChanged (object o, EventArgs e)
202 textbox.IsInEditOrNavigateMode = false;
203 grid.EditRowChanged (this);
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));
238 protected void HideEditBox ()
240 if (!textbox.Visible)
243 grid.SuspendLayout ();
244 textbox.Bounds = Rectangle.Empty;
245 textbox.Visible = false;
246 textbox.IsInEditOrNavigateMode = true;
247 grid.ResumeLayout (false);
250 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum)
252 Paint (g, bounds, source, rowNum, false);
255 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, bool alignToRight)
257 Paint (g, bounds, source, rowNum, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
258 ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
261 protected internal override void Paint (Graphics g, Rectangle bounds, CurrencyManager source, int rowNum, Brush backBrush, Brush foreBrush, bool alignToRight)
263 PaintText (g, bounds, GetFormattedValue (source, rowNum), backBrush, foreBrush, alignToRight);
266 protected void PaintText (Graphics g, Rectangle bounds, string text, bool alignToRight)
268 PaintText (g, bounds, text, ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.BackColor),
269 ThemeEngine.Current.ResPool.GetSolidBrush (DataGridTableStyle.ForeColor), alignToRight);
272 protected void PaintText (Graphics g, Rectangle textBounds, string text, Brush backBrush, Brush foreBrush, bool alignToRight)
274 if (alignToRight == true) {
275 string_format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
277 string_format.FormatFlags &= ~StringFormatFlags.DirectionRightToLeft;
281 case HorizontalAlignment.Center:
282 string_format.Alignment = StringAlignment.Center;
284 case HorizontalAlignment.Right:
285 string_format.Alignment = StringAlignment.Far;
288 string_format.Alignment = StringAlignment.Near;
292 g.FillRectangle (backBrush, textBounds);
293 PaintGridLine (g, textBounds);
295 textBounds.X += offset_x;
296 textBounds.Width -= offset_x;
298 textBounds.Y += offset_y;
299 textBounds.Height -= offset_y;
301 string_format.FormatFlags |= StringFormatFlags.NoWrap;
302 g.DrawString (text, DataGridTableStyle.DataGrid.Font, foreBrush, textBounds, string_format);
306 protected internal override void ReleaseHostedControl ()
311 grid.SuspendLayout ();
312 grid.Controls.Remove (textbox);
313 grid.Invalidate (new Rectangle (textbox.Location, textbox.Size));
316 grid.ResumeLayout (false);
319 protected override void SetDataGridInColumn (DataGrid value)
321 base.SetDataGridInColumn (value);
326 textbox.SetDataGrid (grid);
327 grid.SuspendLayout ();
328 grid.Controls.Add (textbox);
329 grid.ResumeLayout (false);
332 protected internal override void UpdateUI (CurrencyManager source, int rowNum, string displayText)
334 string instantText = 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 = instantText;
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