* TextBoxBase.cs: Take HideSelection into account when
[mono-project.git] / mcs / class / Managed.Windows.Forms / System.Windows.Forms / ListControl.cs
blob5fbc867dbe167a2afdbc95ae21320fe29ef63aca
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.
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) 2004-2005 Novell, Inc.
22 // Authors:
23 // Jordi Mas i Hernandez, jordi@ximian.com
27 // COMPLETE
29 using System;
30 using System.Drawing;
31 using System.Collections;
32 using System.ComponentModel;
33 using System.Reflection;
35 namespace System.Windows.Forms
37 public abstract class ListControl : Control
39 private object data_source;
40 private BindingMemberInfo value_member;
41 private string display_member;
42 private CurrencyManager data_manager;
43 #if NET_2_0
44 private bool formatting_enabled;
45 #endif
47 protected ListControl ()
49 data_source = null;
50 value_member = new BindingMemberInfo (string.Empty);
51 display_member = string.Empty;
52 data_manager = null;
53 SetStyle (ControlStyles.StandardClick | ControlStyles.UserPaint
54 #if NET_2_0
55 | ControlStyles.UseTextForAccessibility
56 #endif
57 , false);
60 #region Events
61 static object DataSourceChangedEvent = new object ();
62 static object DisplayMemberChangedEvent = new object ();
63 static object SelectedValueChangedEvent = new object ();
64 static object ValueMemberChangedEvent = new object ();
66 public event EventHandler DataSourceChanged {
67 add { Events.AddHandler (DataSourceChangedEvent, value); }
68 remove { Events.RemoveHandler (DataSourceChangedEvent, value); }
71 public event EventHandler DisplayMemberChanged {
72 add { Events.AddHandler (DisplayMemberChangedEvent, value); }
73 remove { Events.RemoveHandler (DisplayMemberChangedEvent, value); }
76 public event EventHandler SelectedValueChanged {
77 add { Events.AddHandler (SelectedValueChangedEvent, value); }
78 remove { Events.RemoveHandler (SelectedValueChangedEvent, value); }
81 public event EventHandler ValueMemberChanged {
82 add { Events.AddHandler (ValueMemberChangedEvent, value); }
83 remove { Events.RemoveHandler (ValueMemberChangedEvent, value); }
86 #endregion // Events
88 #region .NET 2.0 Public Properties
89 #if NET_2_0
90 public bool FormattingEnabled {
91 get { return formatting_enabled; }
92 set { formatting_enabled = value; }
94 #endif
95 #endregion
97 #region Public Properties
99 [DefaultValue(null)]
100 [RefreshProperties(RefreshProperties.Repaint)]
101 [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
102 public object DataSource {
103 get { return data_source; }
104 set {
105 if (data_source == value)
106 return;
108 if (value == null)
109 display_member = String.Empty;
110 else if (!(value is IList || value is IListSource))
111 throw new Exception ("Complex DataBinding accepts as a data source " +
112 "either an IList or an IListSource");
114 data_source = value;
115 ConnectToDataSource ();
116 OnDataSourceChanged (EventArgs.Empty);
120 [DefaultValue("")]
121 [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
122 [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, " + Consts.AssemblySystem_Design)]
123 public string DisplayMember {
124 get {
125 return display_member;
127 set {
128 if (value == null)
129 value = String.Empty;
131 if (display_member == value) {
132 return;
135 display_member = value;
136 ConnectToDataSource ();
137 OnDisplayMemberChanged (EventArgs.Empty);
141 public abstract int SelectedIndex {
142 get;
143 set;
146 [Bindable(BindableSupport.Yes)]
147 [Browsable(false)]
148 [DefaultValue(null)]
149 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
150 public object SelectedValue {
151 get {
152 if (data_manager == null) {
153 return null;
156 object item = data_manager [SelectedIndex];
157 object fil = FilterItemOnProperty (item, ValueMember);
158 return fil;
160 set {
161 if (value == null)
162 return;
164 if (value is string) {
165 string valueString = value as string;
166 if (valueString == String.Empty)
167 return;
170 if (data_manager != null) {
172 PropertyDescriptorCollection col = data_manager.GetItemProperties ();
173 PropertyDescriptor prop = col.Find (ValueMember, true);
175 for (int i = 0; i < data_manager.Count; i++) {
176 if (prop.GetValue (data_manager [i]) == value) {
177 SelectedIndex = i;
178 return;
186 [DefaultValue("")]
187 [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
188 public string ValueMember {
189 get { return value_member.BindingMember; }
190 set {
191 BindingMemberInfo new_value = new BindingMemberInfo (value);
193 if (value_member.Equals (new_value)) {
194 return;
197 value_member = new_value;
199 if (display_member == string.Empty) {
200 DisplayMember = value_member.BindingMember;
203 ConnectToDataSource ();
204 OnValueMemberChanged (EventArgs.Empty);
208 #endregion Public Properties
210 #region Public Methods
212 protected object FilterItemOnProperty (object item)
214 return FilterItemOnProperty (item, string.Empty);
217 protected object FilterItemOnProperty (object item, string field)
219 if (item == null)
220 return null;
222 if (field == null || field == string.Empty)
223 return item;
225 PropertyDescriptor prop = null;
227 if (data_manager != null) {
228 PropertyDescriptorCollection col = data_manager.GetItemProperties ();
229 prop = col.Find (field, true);
232 if (prop == null)
233 return item;
235 return prop.GetValue (item);
238 public string GetItemText (object item)
240 if (data_manager != null) {
241 object fil = FilterItemOnProperty (item, DisplayMember);
242 if (fil != null) {
243 return fil.ToString ();
247 return item.ToString ();
250 protected CurrencyManager DataManager {
251 get { return data_manager; }
254 // Used only by ListBox to avoid to break Listbox's member signature
255 protected override bool IsInputKey (Keys keyData)
257 switch (keyData) {
258 case Keys.Up:
259 case Keys.Down:
260 case Keys.PageUp:
261 case Keys.PageDown:
262 case Keys.Right:
263 case Keys.Left:
264 case Keys.End:
265 case Keys.Home:
266 case Keys.ControlKey:
267 case Keys.Space:
268 case Keys.ShiftKey:
269 return true;
271 default:
272 return false;
276 protected override void OnBindingContextChanged (EventArgs e)
278 base.OnBindingContextChanged (e);
279 ConnectToDataSource ();
281 if (DataManager != null) {
282 SetItemsCore (DataManager.List);
283 SelectedIndex = DataManager.Position;
287 protected virtual void OnDataSourceChanged (EventArgs e)
289 EventHandler eh = (EventHandler)(Events [DataSourceChangedEvent]);
290 if (eh != null)
291 eh (this, e);
294 protected virtual void OnDisplayMemberChanged (EventArgs e)
296 EventHandler eh = (EventHandler)(Events [DisplayMemberChangedEvent]);
297 if (eh != null)
298 eh (this, e);
301 protected virtual void OnSelectedIndexChanged (EventArgs e)
303 if (data_manager == null)
304 return;
305 if (data_manager.Position == SelectedIndex)
306 return;
307 data_manager.Position = SelectedIndex;
310 protected virtual void OnSelectedValueChanged (EventArgs e)
312 EventHandler eh = (EventHandler)(Events [SelectedValueChangedEvent]);
313 if (eh != null)
314 eh (this, e);
317 protected virtual void OnValueMemberChanged (EventArgs e)
319 EventHandler eh = (EventHandler)(Events [ValueMemberChangedEvent]);
320 if (eh != null)
321 eh (this, e);
324 protected abstract void RefreshItem (int index);
326 protected virtual void SetItemCore (int index, object value)
331 protected abstract void SetItemsCore (IList items);
333 #endregion Public Methods
335 #region Private Methods
337 internal void BindDataItems ()
339 if (data_manager != null) {
340 SetItemsCore (data_manager.List);
344 private void ConnectToDataSource ()
346 if (data_source == null) {
347 data_manager = null;
348 return;
351 if (BindingContext == null) {
352 return;
355 data_manager = (CurrencyManager) BindingContext [data_source];
356 data_manager.PositionChanged += new EventHandler (OnPositionChanged);
357 data_manager.ItemChanged += new ItemChangedEventHandler (OnItemChanged);
360 private void OnItemChanged (object sender, ItemChangedEventArgs e)
362 /* if the list has changed, tell our subclass to re-bind */
363 if (e.Index == -1)
364 SetItemsCore (data_manager.List);
365 else
366 RefreshItem (e.Index);
369 private void OnPositionChanged (object sender, EventArgs e)
371 SelectedIndex = data_manager.Position;
374 #endregion Private Methods