12b93c1489fd28bb464d838ae9b1eadc087e0a4e
[mono.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / DataGridViewComboBoxCell.cs
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.
19 //
20 // Copyright (c) 2005 Novell, Inc. (http://www.novell.com)
21 //
22 // Author:
23 //      Pedro Martínez Juliá <pedromj@gmail.com>
24 //
25
26
27 #if NET_2_0
28
29 using System.Collections;
30 using System.ComponentModel;
31 using System.Drawing;
32
33 namespace System.Windows.Forms {
34
35         public class DataGridViewComboBoxCell : DataGridViewCell {
36
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;
48
49                 private DataGridViewComboBoxEditingControl editingControl;
50
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;
61                 }
62
63                 [DefaultValue (true)]
64                 public virtual bool AutoComplete {
65                         get { return autoComplete; }
66                         set { autoComplete = value; }
67                 }
68
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;
75                                 }
76                                 throw new Exception("Value is no IList, IListSource or null.");
77                         }
78                 }
79
80                 [DefaultValue ("")]
81                 public virtual string DisplayMember {
82                         get { return displayMember; }
83                         set { displayMember = value; }
84                 }
85
86                 [DefaultValue (DataGridViewComboBoxDisplayStyle.DropDownButton)]
87                 public DataGridViewComboBoxDisplayStyle DisplayStyle {
88                         get { return displayStyle; }
89                         set { displayStyle = value; }
90                 }
91
92                 [DefaultValue (false)]
93                 public bool DisplayStyleForCurrentCellOnly {
94                         get { return displayStyleForCurrentCellOnly; }
95                         set { displayStyleForCurrentCellOnly = value; }
96                 }
97
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.");
104                                 }
105                                 dropDownWidth = value;
106                         }
107                 }
108
109                 public override Type EditType {
110                         get { return typeof(DataGridViewComboBoxEditingControl); }
111                 }
112
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.");
119                                 }
120                                 flatStyle = value;
121                         }
122                 }
123
124                 public override Type FormattedValueType {
125                         get { return typeof(string); }
126                 }
127
128                 [Browsable (false)]
129                 public virtual ObjectCollection Items {
130                         get { return items; }
131                 }
132
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.");
139                                 }
140                                 maxDropDownItems = value;
141                         }
142                 }
143
144                 [DefaultValue (false)]
145                 public virtual bool Sorted {
146                         get { return sorted; }
147                         set {
148                                 /*
149                                 if () {
150                                         throw new ArgumentException("Cannot sort a cell attached to a data source.");
151                                 }
152                                 */
153                                 sorted = value;
154                         }
155                 }
156
157                 [DefaultValue ("")]
158                 public virtual string ValueMember {
159                         get { return valueMember; }
160                         set { valueMember = value; }
161                 }
162
163                 public override Type ValueType {
164                         get { return typeof(string); }
165                 }
166
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;
179                 }
180
181                 public override void DetachEditingControl () {
182                         this.DataGridView.EditingControlInternal = null;
183                 }
184
185                 public override void InitializeEditingControl (int rowIndex, object initialFormattedValue, DataGridViewCellStyle dataGridViewCellStyle) {
186                         base.InitializeEditingControl (rowIndex, initialFormattedValue, dataGridViewCellStyle);
187                         
188                         editingControl = DataGridView.EditingControl as DataGridViewComboBoxEditingControl;
189                         
190                         if (editingControl == null)
191                                 return;
192                         
193                         // A simple way to check if the control has
194                         // been initialized already.
195                         if (editingControl.Items.Count > 0)
196                                 return;
197                         
198                         editingControl.DropDownStyle = ComboBoxStyle.DropDownList;
199                         editingControl.Text = initialFormattedValue == null ? string.Empty : initialFormattedValue.ToString ();
200                         editingControl.SelectedIndexChanged += new EventHandler (editingControl_SelectedIndexChanged);
201                         editingControl.Items.Clear ();
202                         editingControl.Items.AddRange (this.Items);             
203                 }
204
205                 void editingControl_SelectedIndexChanged (object sender, EventArgs e)
206                 {
207                         Value = editingControl.SelectedItem;
208                 }
209
210                 public override bool KeyEntersEditMode (KeyEventArgs e) {
211                         throw new NotImplementedException();
212                 }
213
214                 public override object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) {
215                         throw new NotImplementedException();
216                 }
217
218                 public override string ToString () {
219                         return string.Format ("DataGridViewComboBoxCell {{ ColumnIndex={0}, RowIndex={1} }}", ColumnIndex, RowIndex);
220                 }
221
222                 protected override Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) {
223                         throw new NotImplementedException();
224                 }
225
226                 protected override Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) {
227                         throw new NotImplementedException();
228                 }
229
230                 protected override object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) {
231                         throw new NotImplementedException();
232                 }
233
234                 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) {
235                         throw new NotImplementedException();
236                 }
237
238                 protected override void OnDataGridViewChanged () {
239                         // Here we're supposed to do something with DataSource, etc, according to MSDN.
240                         base.OnDataGridViewChanged ();
241                 }
242
243                 protected override void OnEnter (int rowIndex, bool throughMouseClick) {
244                         base.OnEnter (rowIndex, throughMouseClick);
245                 }
246
247                 protected override void OnLeave (int rowIndex, bool throughMouseClick) {
248                         base.OnLeave (rowIndex, throughMouseClick);
249                 }
250
251                 protected override void OnMouseClick (DataGridViewCellMouseEventArgs e) {
252                         base.OnMouseClick (e);
253                 }
254
255                 protected override void OnMouseEnter (int rowIndex) {
256                         base.OnMouseEnter (rowIndex);
257                 }
258
259                 protected override void OnMouseLeave (int rowIndex) {
260                         base.OnMouseLeave (rowIndex);
261                 }
262
263                 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e) {
264                         //Console.WriteLine ("MouseMove (Location: {0}", e.Location);
265                         base.OnMouseMove (e);
266                 }
267
268                 protected override void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds, 
269                                 int rowIndex, DataGridViewElementStates elementeState, object value, 
270                                 object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle, 
271                                 DataGridViewPaintParts paintParts) {
272                         
273                         
274                         Rectangle button_area, text_area;
275                         text_area = cellBounds;
276                         button_area = CalculateButtonArea (cellBounds);
277                         
278                         graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (cellStyle.BackColor), cellBounds);
279                         ThemeEngine.Current.CPDrawComboButton (graphics, button_area, ButtonState.Normal);
280                         
281                         string text;
282                         if (formattedValue == null)
283                                 text = string.Empty;
284                         else {
285                                 text = formattedValue.ToString ();
286                         }
287                         
288                         graphics.DrawString (text, cellStyle.Font, ThemeEngine.Current.ResPool.GetSolidBrush (cellStyle.ForeColor), text_area, StringFormat.GenericTypographic);
289                 }
290
291                 private Rectangle CalculateButtonArea (Rectangle cellBounds)
292                 {
293                         Rectangle button_area, text_area;
294                         int border = ThemeEngine.Current.Border3DSize.Width;
295                         const int button_width = 16;
296
297                         text_area = cellBounds;
298
299                         button_area = cellBounds;
300                         button_area.X = text_area.Right - button_width - border;
301                         button_area.Y = text_area.Y + border;
302                         button_area.Width = button_width;
303                         button_area.Height = text_area.Height - 2 * border;
304                         
305                         return button_area;
306                 }
307
308                 [ListBindable (false)]
309                 public class ObjectCollection : IList, ICollection, IEnumerable {
310
311                         private ArrayList list;
312
313                         //private DataGridViewComboBoxCell owner;
314
315                         public ObjectCollection (DataGridViewComboBoxCell owner) {
316                                 //this.owner = owner;
317                                 list = new ArrayList();
318                         }
319
320                         public int Count {
321                                 get { return list.Count; }
322                         }
323
324                         bool IList.IsFixedSize {
325                                 get { return list.IsFixedSize; }
326                         }
327
328                         public bool IsReadOnly {
329                                 get { return list.IsReadOnly; }
330                         }
331
332                         bool ICollection.IsSynchronized {
333                                 get { return list.IsSynchronized; }
334                         }
335
336                         object ICollection.SyncRoot {
337                                 get { return list.SyncRoot; }
338                         }
339
340                         public virtual object this [int index] {
341                                 get { return list[index]; }
342                                 set { list[index] = value; }
343                         }
344
345                         public int Add (object item) {
346                                 return list.Add(item);
347                         }
348
349                         public void AddRange (ObjectCollection value) {
350                                 list.AddRange(value.list);
351                         }
352
353                         public void AddRange (params object[] items) {
354                                 list.AddRange(items);
355                         }
356
357                         public void Clear () {
358                                 list.Clear();
359                         }
360
361                         public bool Contains (object value) {
362                                 return list.Contains(value);
363                         }
364
365                         void ICollection.CopyTo (Array destination, int arrayIndex)
366                         {
367                                 CopyTo ((object[])destination, arrayIndex);
368                         }
369
370                         public void CopyTo (object[] destination, int arrayIndex) {
371                                 list.CopyTo(destination, arrayIndex);
372                         }
373
374                         public IEnumerator GetEnumerator () {
375                                 return list.GetEnumerator();
376                         }
377
378                         public int IndexOf (object value) {
379                                 return list.IndexOf(value);
380                         }
381
382                         public void Insert (int index, object item) {
383                                 list.Insert(index, item);
384                         }
385
386                         public void Remove (object value) {
387                                 list.Remove(value);
388                         }
389
390                         public void RemoveAt (int index) {
391                                 list.RemoveAt(index);
392                         }
393
394
395                         int IList.Add (object value)
396                         {
397                                 return Add (value);
398                         }
399
400                 }
401
402         }
403
404 }
405
406 #endif