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) 2004-2005 Novell, Inc.
23 // Jordi Mas i Hernandez, jordi@ximian.com
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;
44 protected ListControl ()
47 value_member = new BindingMemberInfo (string.Empty);
48 display_member = string.Empty;
50 SetStyle (ControlStyles.StandardClick | ControlStyles.UserPaint, false);
54 public event EventHandler DataSourceChanged;
55 public event EventHandler DisplayMemberChanged;
56 public event EventHandler SelectedValueChanged;
57 public event EventHandler ValueMemberChanged;
60 #region Public Properties
63 [RefreshProperties(RefreshProperties.Repaint)]
64 [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
65 public object DataSource {
66 get { return data_source; }
68 if (!(value is IList || value is IListSource)) {
69 throw new Exception ("Complex DataBinding accepts as a data source " +
70 "either an IList or an IListSource");
73 if (data_source == value)
77 ConnectToDataSource ();
78 OnDataSourceChanged (EventArgs.Empty);
83 [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
84 [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, " + Consts.AssemblySystem_Design)]
85 public string DisplayMember {
87 return display_member;
90 if (display_member == value) {
94 display_member = value;
95 ConnectToDataSource ();
96 OnDisplayMemberChanged (EventArgs.Empty);
100 public abstract int SelectedIndex {
105 [Bindable(BindableSupport.Yes)]
108 [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
109 public object SelectedValue {
111 if (data_manager == null) {
115 object item = data_manager.GetItem (SelectedIndex);
116 object fil = FilterItemOnProperty (item, ValueMember);
120 if (data_manager != null) {
122 PropertyDescriptorCollection col = data_manager.GetItemProperties ();
123 PropertyDescriptor prop = col.Find (ValueMember, true);
125 for (int i = 0; i < data_manager.Count; i++) {
126 if (prop.GetValue (data_manager.GetItem (i)) == value) {
137 [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
138 public string ValueMember {
139 get { return value_member.BindingMember; }
141 BindingMemberInfo new_value = new BindingMemberInfo (value);
143 if (value_member.Equals (new_value)) {
147 value_member = new_value;
149 if (display_member == string.Empty) {
150 DisplayMember = value_member.BindingMember;
153 ConnectToDataSource ();
154 OnValueMemberChanged (EventArgs.Empty);
158 #endregion Public Properties
160 #region Public Methods
162 protected object FilterItemOnProperty (object item)
164 return FilterItemOnProperty (item, string.Empty);
167 protected object FilterItemOnProperty (object item, string field)
172 if (field == null || field == string.Empty)
175 PropertyDescriptor prop = null;
177 if (data_manager != null) {
178 PropertyDescriptorCollection col = data_manager.GetItemProperties ();
179 prop = col.Find (field, true);
185 return prop.GetValue (item);
188 public string GetItemText (object item)
190 if (data_manager != null) {
191 object fil = FilterItemOnProperty (item, DisplayMember);
193 return fil.ToString ();
197 return item.ToString ();
200 protected CurrencyManager DataManager {
201 get { return data_manager; }
204 // Used only by ListBox to avoid to break Listbox's member signature
205 protected override bool IsInputKey (Keys keyData)
216 case Keys.ControlKey:
226 protected override void OnBindingContextChanged (EventArgs e)
228 base.OnBindingContextChanged (e);
229 ConnectToDataSource ();
231 if (DataManager != null) {
232 SetItemsCore (DataManager.List);
233 SelectedIndex = DataManager.Position;
237 protected virtual void OnDataSourceChanged (EventArgs e)
239 if (DataSourceChanged != null)
240 DataSourceChanged (this,e);
243 protected virtual void OnDisplayMemberChanged (EventArgs e)
245 if (DisplayMemberChanged != null)
246 DisplayMemberChanged (this, e);
249 protected virtual void OnSelectedIndexChanged (EventArgs e)
251 if (data_manager == null)
253 if (data_manager.Position == SelectedIndex)
255 data_manager.Position = SelectedIndex;
258 protected virtual void OnSelectedValueChanged (EventArgs e)
260 if (SelectedValueChanged != null)
261 SelectedValueChanged (this, e);
264 protected virtual void OnValueMemberChanged (EventArgs e)
266 if (ValueMemberChanged != null)
267 ValueMemberChanged (this, e);
270 protected abstract void RefreshItem (int index);
272 protected virtual void SetItemCore (int index, object value)
277 protected abstract void SetItemsCore (IList items);
279 #endregion Public Methods
281 #region Private Methods
283 internal void BindDataItems (IList items)
287 if (data_manager != null) {
288 SetItemsCore (data_manager.List);
292 private void ConnectToDataSource ()
294 if (data_source == null) {
299 if (BindingContext == null) {
303 data_manager = (CurrencyManager) BindingContext [data_source];
304 data_manager.PositionChanged += new EventHandler (OnPositionChanged);
307 private void OnPositionChanged (object sender, EventArgs e)
309 SelectedIndex = data_manager.Position;
312 #endregion Private Methods