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)
228 if (DataGridView == null || string.IsNullOrEmpty (ErrorText))
229 return Rectangle.Empty;
231 Size error_icon = new Size (12, 11);
232 return new Rectangle (new Point (Size.Width - error_icon.Width - 23, (Size.Height - error_icon.Height) / 2), error_icon);
235 protected override object GetFormattedValue (object value, int rowIndex, ref DataGridViewCellStyle cellStyle, TypeConverter valueTypeConverter, TypeConverter formattedValueTypeConverter, DataGridViewDataErrorContexts context) {
236 throw new NotImplementedException();
239 protected override Size GetPreferredSize (Graphics graphics, DataGridViewCellStyle cellStyle, int rowIndex, Size constraintSize) {
240 throw new NotImplementedException();
243 protected override void OnDataGridViewChanged () {
244 // Here we're supposed to do something with DataSource, etc, according to MSDN.
245 base.OnDataGridViewChanged ();
248 protected override void OnEnter (int rowIndex, bool throughMouseClick) {
249 base.OnEnter (rowIndex, throughMouseClick);
252 protected override void OnLeave (int rowIndex, bool throughMouseClick) {
253 base.OnLeave (rowIndex, throughMouseClick);
256 protected override void OnMouseClick (DataGridViewCellMouseEventArgs e) {
257 base.OnMouseClick (e);
260 protected override void OnMouseEnter (int rowIndex) {
261 base.OnMouseEnter (rowIndex);
264 protected override void OnMouseLeave (int rowIndex) {
265 base.OnMouseLeave (rowIndex);
268 protected override void OnMouseMove (DataGridViewCellMouseEventArgs e) {
269 //Console.WriteLine ("MouseMove (Location: {0}", e.Location);
270 base.OnMouseMove (e);
273 protected override void Paint (Graphics graphics, Rectangle clipBounds, Rectangle cellBounds,
274 int rowIndex, DataGridViewElementStates elementState, object value,
275 object formattedValue, string errorText, DataGridViewCellStyle cellStyle, DataGridViewAdvancedBorderStyle advancedBorderStyle,
276 DataGridViewPaintParts paintParts) {
279 Rectangle button_area, text_area;
280 text_area = cellBounds;
281 button_area = CalculateButtonArea (cellBounds);
283 graphics.FillRectangle (ThemeEngine.Current.ResPool.GetSolidBrush (cellStyle.BackColor), cellBounds);
284 ThemeEngine.Current.CPDrawComboButton (graphics, button_area, ButtonState.Normal);
287 if (formattedValue == null)
290 text = formattedValue.ToString ();
293 graphics.DrawString (text, cellStyle.Font, ThemeEngine.Current.ResPool.GetSolidBrush (cellStyle.ForeColor), text_area, StringFormat.GenericTypographic);
296 private Rectangle CalculateButtonArea (Rectangle cellBounds)
298 Rectangle button_area, text_area;
299 int border = ThemeEngine.Current.Border3DSize.Width;
300 const int button_width = 16;
302 text_area = cellBounds;
304 button_area = cellBounds;
305 button_area.X = text_area.Right - button_width - border;
306 button_area.Y = text_area.Y + border;
307 button_area.Width = button_width;
308 button_area.Height = text_area.Height - 2 * border;
313 [ListBindable (false)]
314 public class ObjectCollection : IList, ICollection, IEnumerable {
316 private ArrayList list;
318 //private DataGridViewComboBoxCell owner;
320 public ObjectCollection (DataGridViewComboBoxCell owner) {
321 //this.owner = owner;
322 list = new ArrayList();
326 get { return list.Count; }
329 bool IList.IsFixedSize {
330 get { return list.IsFixedSize; }
333 public bool IsReadOnly {
334 get { return list.IsReadOnly; }
337 bool ICollection.IsSynchronized {
338 get { return list.IsSynchronized; }
341 object ICollection.SyncRoot {
342 get { return list.SyncRoot; }
345 public virtual object this [int index] {
346 get { return list[index]; }
347 set { list[index] = value; }
350 public int Add (object item) {
351 return list.Add(item);
354 public void AddRange (ObjectCollection value) {
355 list.AddRange(value.list);
358 public void AddRange (params object[] items) {
359 list.AddRange(items);
362 public void Clear () {
366 public bool Contains (object value) {
367 return list.Contains(value);
370 void ICollection.CopyTo (Array destination, int index)
372 CopyTo ((object[]) destination, index);
375 public void CopyTo (object[] destination, int arrayIndex)
377 list.CopyTo (destination, arrayIndex);
380 public IEnumerator GetEnumerator () {
381 return list.GetEnumerator();
384 public int IndexOf (object value) {
385 return list.IndexOf(value);
388 public void Insert (int index, object item) {
389 list.Insert(index, item);
392 public void Remove (object value) {
396 public void RemoveAt (int index) {
397 list.RemoveAt(index);
401 int IList.Add (object item)