In System.Windows.Forms:
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridViewComboBoxCell.cs
blob1d258b38932b7e05295049abb0d89c8d6f4bc4de
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:
8 //
9 // The above copyright notice and this permission notice shall be
10 // included in all copies or substantial portions of the Software.
11 //
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)
22 // Author:
23 // Pedro Martínez Juliá <pedromj@gmail.com>
27 #if NET_2_0
29 using System.Collections;
30 using System.ComponentModel;
31 using System.Drawing;
33 namespace System.Windows.Forms {
35 public class DataGridViewComboBoxCell : DataGridViewCell {
37 private bool autoComplete;
38 private object dataSource;
39 private string displayMember;
40 private DataGridViewComboBoxDisplayStyle displayStyle;
41 private bool displayStyleForCurrentCellOnly;
42 private int dropDownWidth;
43 private FlatStyle flatStyle;
44 private ObjectCollection items;
45 private int maxDropDownItems;
46 private bool sorted;
47 private string valueMember;
49 private DataGridViewComboBoxEditingControl editingControl;
51 public DataGridViewComboBoxCell () : base() {
52 autoComplete = true;
53 dataSource = null;
54 displayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
55 displayStyleForCurrentCellOnly = false;
56 dropDownWidth = 1;
57 flatStyle = FlatStyle.Standard;
58 items = new ObjectCollection(this);
59 maxDropDownItems = 8;
60 sorted = false;
63 [DefaultValue (true)]
64 public virtual bool AutoComplete {
65 get { return autoComplete; }
66 set { autoComplete = value; }
69 public virtual object DataSource {
70 get { return dataSource; }
71 set {
72 if (value is IList || value is IListSource || value == null) {
73 dataSource = value;
74 return;
76 throw new Exception("Value is no IList, IListSource or null.");
80 [DefaultValue ("")]
81 public virtual string DisplayMember {
82 get { return displayMember; }
83 set { displayMember = value; }
86 [DefaultValue (DataGridViewComboBoxDisplayStyle.DropDownButton)]
87 public DataGridViewComboBoxDisplayStyle DisplayStyle {
88 get { return displayStyle; }
89 set { displayStyle = value; }
92 [DefaultValue (false)]
93 public bool DisplayStyleForCurrentCellOnly {
94 get { return displayStyleForCurrentCellOnly; }
95 set { displayStyleForCurrentCellOnly = value; }
98 [DefaultValue (1)]
99 public virtual int DropDownWidth {
100 get { return dropDownWidth; }
101 set {
102 if (value < 1) {
103 throw new ArgumentOutOfRangeException("Value is less than 1.");
105 dropDownWidth = value;
109 public override Type EditType {
110 get { return typeof(DataGridViewComboBoxEditingControl); }
113 [DefaultValue (FlatStyle.Standard)]
114 public FlatStyle FlatStyle {
115 get { return flatStyle; }
116 set {
117 if (!Enum.IsDefined(typeof(FlatStyle), value)) {
118 throw new InvalidEnumArgumentException("Value is not valid FlatStyle.");
120 flatStyle = value;
124 public override Type FormattedValueType {
125 get { return typeof(string); }
128 [Browsable (false)]
129 public virtual ObjectCollection Items {
130 get { return items; }
133 [DefaultValue (8)]
134 public virtual int MaxDropDownItems {
135 get { return maxDropDownItems; }
136 set {
137 if (value < 1 || value > 100) {
138 throw new ArgumentOutOfRangeException("Value is less than 1 or greater than 100.");
140 maxDropDownItems = value;
144 [DefaultValue (false)]
145 public virtual bool Sorted {
146 get { return sorted; }
147 set {
149 if () {
150 throw new ArgumentException("Cannot sort a cell attached to a data source.");
153 sorted = value;
157 [DefaultValue ("")]
158 public virtual string ValueMember {
159 get { return valueMember; }
160 set { valueMember = value; }
163 public override Type ValueType {
164 get { return typeof(string); }
167 public override object Clone () {
168 DataGridViewComboBoxCell cell = (DataGridViewComboBoxCell) base.Clone();
169 cell.autoComplete = this.autoComplete;
170 cell.dataSource = this.dataSource;
171 cell.displayStyle = this.displayStyle;
172 cell.displayStyleForCurrentCellOnly = this.displayStyleForCurrentCellOnly;
173 cell.dropDownWidth = this.dropDownWidth;
174 cell.flatStyle = this.flatStyle;
175 cell.items.AddRange(this.items);
176 cell.maxDropDownItems = this.maxDropDownItems;
177 cell.sorted = this.sorted;
178 return cell;
181 public override void DetachEditingControl () {
182 this.DataGridView.EditingControlInternal = null;
185 public override void InitializeEditingControl (int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) {
186 base.InitializeEditingControl (rowIndex, initialFormattedValue, dataGridViewCellStyle);
188 editingControl = DataGridView.EditingControl as DataGridViewComboBoxEditingControl;
190 if (editingControl == null)
191 return;
193 string text = initialFormattedValue == null ? string.Empty : initialFormattedValue.ToString ();
195 // A simple way to check if the control has
196 // been initialized already.
197 if (editingControl.Items.Count > 0) {
198 editingControl.SelectedIndex = editingControl.FindString (text);
199 return;
202 editingControl.DropDownStyle = ComboBoxStyle.DropDownList;
203 editingControl.Items.AddRange (this.Items);
205 editingControl.Sorted = sorted;
206 editingControl.SelectedIndex = editingControl.FindString (text);
208 editingControl.SelectedIndexChanged += new EventHandler (editingControl_SelectedIndexChanged);
211 void editingControl_SelectedIndexChanged (object sender, EventArgs e)
213 Value = editingControl.SelectedItem;
216 public override bool KeyEntersEditMode (KeyEventArgs e)
218 if (e.KeyCode == Keys.Space)
219 return true;
220 if ((int)e.KeyCode >= 48 && (int)e.KeyCode <= 90)
221 return true;
222 if ((int)e.KeyCode >= 96 && (int)e.KeyCode <= 111)
223 return true;
224 if (e.KeyCode == Keys.BrowserSearch || e.KeyCode == Keys.SelectMedia)
225 return true;
226 if ((int)e.KeyCode >= 186 && (int)e.KeyCode <= 229)
227 return true;
228 if (e.KeyCode == Keys.Attn || e.KeyCode == Keys.Packet)
229 return true;
230 if ((int)e.KeyCode >= 248 && (int)e.KeyCode <= 254)
231 return true;
232 if (e.KeyCode == Keys.F4)
233 return true;
234 if ((e.Modifiers == Keys.Alt) && (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up))
235 return true;
237 return false;
240 public override object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter)
242 return base.ParseFormattedValue (formattedValue, cellStyle, formattedValueTypeConverter, valueTypeConverter);
245 public override string ToString () {
246 return string.Format ("DataGridViewComboBoxCell {{ ColumnIndex={0}, RowIndex={1} }}", ColumnIndex, RowIndex);
249 protected override Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
251 if (DataGridView == null)
252 return Rectangle.Empty;
254 object o = FormattedValue;
255 Size s = Size.Empty;
257 if (o != null)
258 s = DataGridViewCell.MeasureTextSize (graphics, o.ToString (), cellStyle.Font, TextFormatFlags.Default);
260 return new Rectangle (1, (OwningRow.Height - s.Height) / 2, s.Width - 3, s.Height);
263 protected override Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex)
265 if (DataGridView == null || string.IsNullOrEmpty (ErrorText))
266 return Rectangle.Empty;
268 Size error_icon = new Size (12, 11);
269 return new Rectangle (new Point (Size.Width - error_icon.Width - 23, (Size.Height - error_icon.Height) / 2), error_icon);
272 protected override object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context)
274 return base.GetFormattedValue (value, rowIndex, ref cellStyle, valueTypeConverter, formattedValueTypeConverter, context);
277 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize)
279 object o = FormattedValue;
281 if (o != null) {
282 Size s = DataGridViewCell.MeasureTextSize (graphics, o.ToString (), cellStyle.Font, TextFormatFlags.Default);
283 s.Height = Math.Max (s.Height, 22);
284 s.Width += 25;
285 return s;
286 } else
287 return new Size (39, 22);
290 protected override void OnDataGridViewChanged () {
291 // Here we're supposed to do something with DataSource, etc, according to MSDN.
292 base.OnDataGridViewChanged ();
295 protected override void OnEnter (int rowIndex, bool throughMouseClick) {
296 base.OnEnter (rowIndex, throughMouseClick);
299 protected override void OnLeave (int rowIndex, bool throughMouseClick) {
300 base.OnLeave (rowIndex, throughMouseClick);
303 protected override void OnMouseClick (DataGridViewCellMouseEventArgs e) {
304 base.OnMouseClick (e);
307 protected override void OnMouseEnter (int rowIndex) {
308 base.OnMouseEnter (rowIndex);
311 protected override void OnMouseLeave (int rowIndex) {
312 base.OnMouseLeave (rowIndex);
315 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e) {
316 //Console.WriteLine ("MouseMove (Location: {0}", e.Location);
317 base.OnMouseMove (e);
320 protected override void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, int rowIndex, DataGridViewElementStates elementState, object value, object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, DataGridViewPaintParts paintParts)
322 // The internal paint routines are overridden instead of
323 // doing the custom paint logic here
324 base.Paint (graphics, clipBounds, cellBounds, rowIndex, elementState, value, formattedValue, errorText, cellStyle, advancedBorderStyle, paintParts);
327 internal override void PaintPartContent (Graphics graphics, Rectangle cellBounds, int rowIndex, DataGridViewElementStates cellState, DataGridViewCellStyle cellStyle, object formattedValue)
329 Color color = Selected ? cellStyle.SelectionForeColor : cellStyle.ForeColor;
330 TextFormatFlags flags = TextFormatFlags.EndEllipsis | TextFormatFlags.VerticalCenter | TextFormatFlags.TextBoxControl;
332 Rectangle text_area = ContentBounds;
333 text_area.X += cellBounds.X;
334 text_area.Y += cellBounds.Y;
336 Rectangle button_area = CalculateButtonArea (cellBounds);
338 // The background of the dropdown button should be gray, not
339 // the background color of the cell.
340 graphics.FillRectangle (SystemBrushes.Control, button_area);
341 ThemeEngine.Current.CPDrawComboButton (graphics, button_area, ButtonState.Normal);
343 if (formattedValue != null)
344 TextRenderer.DrawText (graphics, formattedValue.ToString (), cellStyle.Font, text_area, color, flags);
347 private Rectangle CalculateButtonArea (Rectangle cellBounds)
349 Rectangle button_area, text_area;
350 int border = ThemeEngine.Current.Border3DSize.Width;
351 const int button_width = 16;
353 text_area = cellBounds;
355 button_area = cellBounds;
356 button_area.X = text_area.Right - button_width - border;
357 button_area.Y = text_area.Y + border;
358 button_area.Width = button_width;
359 button_area.Height = text_area.Height - 2 * border;
361 return button_area;
364 [ListBindable (false)]
365 public class ObjectCollection : IList, ICollection, IEnumerable {
367 private ArrayList list;
369 //private DataGridViewComboBoxCell owner;
371 public ObjectCollection (DataGridViewComboBoxCell owner) {
372 //this.owner = owner;
373 list = new ArrayList();
376 public int Count {
377 get { return list.Count; }
380 bool IList.IsFixedSize {
381 get { return list.IsFixedSize; }
384 public bool IsReadOnly {
385 get { return list.IsReadOnly; }
388 bool ICollection.IsSynchronized {
389 get { return list.IsSynchronized; }
392 object ICollection.SyncRoot {
393 get { return list.SyncRoot; }
396 public virtual object this [int index] {
397 get { return list[index]; }
398 set { list[index] = value; }
401 public int Add (object item) {
402 return list.Add(item);
405 public void AddRange (ObjectCollection value) {
406 list.AddRange(value.list);
409 public void AddRange (params object[] items) {
410 list.AddRange(items);
413 public void Clear () {
414 list.Clear();
417 public bool Contains (object value) {
418 return list.Contains(value);
421 void ICollection.CopyTo (Array destination, int index)
423 CopyTo ((object[]) destination, index);
426 public void CopyTo (object[] destination, int arrayIndex)
428 list.CopyTo (destination, arrayIndex);
431 public IEnumerator GetEnumerator () {
432 return list.GetEnumerator();
435 public int IndexOf (object value) {
436 return list.IndexOf(value);
439 public void Insert (int index, object item) {
440 list.Insert(index, item);
443 public void Remove (object value) {
444 list.Remove(value);
447 public void RemoveAt (int index) {
448 list.RemoveAt(index);
452 int IList.Add (object item)
454 return Add (item);
463 #endif