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 // Pedro MartÃnez Juliá <pedromj@gmail.com>
29 using System.Collections;
30 using System.ComponentModel;
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;
47 private string valueMember;
49 private DataGridViewComboBoxEditingControl editingControl;
51 public DataGridViewComboBoxCell () : base() {
54 displayStyle = DataGridViewComboBoxDisplayStyle.DropDownButton;
55 displayStyleForCurrentCellOnly = false;
57 flatStyle = FlatStyle.Standard;
58 items = new ObjectCollection(this);
64 public virtual bool AutoComplete {
65 get { return autoComplete; }
66 set { autoComplete = value; }
69 public virtual object DataSource {
70 get { return dataSource; }
72 if (value is IList || value is IListSource || value == null) {
76 throw new Exception("Value is no IList, IListSource or null.");
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; }
99 public virtual int DropDownWidth {
100 get { return dropDownWidth; }
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; }
117 if (!Enum.IsDefined(typeof(FlatStyle), value)) {
118 throw new InvalidEnumArgumentException("Value is not valid FlatStyle.");
124 public override Type FormattedValueType {
125 get { return typeof(string); }
129 public virtual ObjectCollection Items {
130 get { return items; }
134 public virtual int MaxDropDownItems {
135 get { return maxDropDownItems; }
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; }
150 throw new ArgumentException("Cannot sort a cell attached to a data source.");
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;
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)
193 // A simple way to check if the control has
194 // been initialized already.
195 if (editingControl.Items.Count > 0)
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);
205 void editingControl_SelectedIndexChanged (object sender, EventArgs e)
207 Value = editingControl.SelectedItem;
210 public override bool KeyEntersEditMode (KeyEventArgs e) {
211 throw new NotImplementedException();
214 public override object ParseFormattedValue (object formattedValue, DataGridViewCellStyle cellStyle, TypeConverter formattedValueTypeConverter, TypeConverter valueTypeConverter) {
215 throw new NotImplementedException();
218 public override string ToString () {
219 return string.Format ("DataGridViewComboBoxCell {{ ColumnIndex={0}, RowIndex={1} }}", ColumnIndex, RowIndex);
222 protected override Rectangle GetContentBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) {
223 throw new NotImplementedException();
226 protected override Rectangle GetErrorIconBounds (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex) {
227 throw new NotImplementedException();
230 protected override object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) {
231 throw new NotImplementedException();
234 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) {
235 throw new NotImplementedException();
238 protected override void OnDataGridViewChanged () {
239 // Here we're supposed to do something with DataSource, etc, according to MSDN.
240 base.OnDataGridViewChanged ();
243 protected override void OnEnter (int rowIndex, bool throughMouseClick) {
244 base.OnEnter (rowIndex, throughMouseClick);
247 protected override void OnLeave (int rowIndex, bool throughMouseClick) {
248 base.OnLeave (rowIndex, throughMouseClick);
251 protected override void OnMouseClick (DataGridViewCellMouseEventArgs e) {
252 base.OnMouseClick (e);
255 protected override void OnMouseEnter (int rowIndex) {
256 base.OnMouseEnter (rowIndex);
259 protected override void OnMouseLeave (int rowIndex) {
260 base.OnMouseLeave (rowIndex);
263 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e) {
264 //Console.WriteLine ("MouseMove (Location: {0}", e.Location);
265 base.OnMouseMove (e);
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) {
274 Rectangle button_area, text_area;
275 text_area = cellBounds;
276 button_area = CalculateButtonArea (cellBounds);
278 graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (cellStyle.BackColor), cellBounds);
279 ThemeEngine.Current.CPDrawComboButton (graphics, button_area, ButtonState.Normal);
282 if (formattedValue == null)
285 text = formattedValue.ToString ();
288 graphics.DrawString (text, cellStyle.Font, ThemeEngine.Current.ResPool.GetSolidBrush (cellStyle.ForeColor), text_area, StringFormat.GenericTypographic);
291 private Rectangle CalculateButtonArea (Rectangle cellBounds)
293 Rectangle button_area, text_area;
294 int border = ThemeEngine.Current.Border3DSize.Width;
295 const int button_width = 16;
297 text_area = cellBounds;
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;
308 [ListBindable (false)]
309 public class ObjectCollection : IList, ICollection, IEnumerable {
311 private ArrayList list;
313 //private DataGridViewComboBoxCell owner;
315 public ObjectCollection (DataGridViewComboBoxCell owner) {
316 //this.owner = owner;
317 list = new ArrayList();
321 get { return list.Count; }
324 bool IList.IsFixedSize {
325 get { return list.IsFixedSize; }
328 public bool IsReadOnly {
329 get { return list.IsReadOnly; }
332 bool ICollection.IsSynchronized {
333 get { return list.IsSynchronized; }
336 object ICollection.SyncRoot {
337 get { return list.SyncRoot; }
340 public virtual object this [int index] {
341 get { return list[index]; }
342 set { list[index] = value; }
345 public int Add (object item) {
346 return list.Add(item);
349 public void AddRange (ObjectCollection value) {
350 list.AddRange(value.list);
353 public void AddRange (params object[] items) {
354 list.AddRange(items);
357 public void Clear () {
361 public bool Contains (object value) {
362 return list.Contains(value);
365 void ICollection.CopyTo (Array destination, int arrayIndex)
367 CopyTo ((object[])destination, arrayIndex);
370 public void CopyTo (object[] destination, int arrayIndex) {
371 list.CopyTo(destination, arrayIndex);
374 public IEnumerator GetEnumerator () {
375 return list.GetEnumerator();
378 public int IndexOf (object value) {
379 return list.IndexOf(value);
382 public void Insert (int index, object item) {
383 list.Insert(index, item);
386 public void Remove (object value) {
390 public void RemoveAt (int index) {
391 list.RemoveAt(index);
395 int IList.Add (object value)