ListControl.cs 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316
  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) 2004-2005 Novell, Inc.
  21. //
  22. // Authors:
  23. // Jordi Mas i Hernandez, [email protected]
  24. //
  25. //
  26. // COMPLETE
  27. using System;
  28. using System.Drawing;
  29. using System.Collections;
  30. using System.ComponentModel;
  31. using System.Reflection;
  32. namespace System.Windows.Forms
  33. {
  34. public abstract class ListControl : Control
  35. {
  36. private object data_source;
  37. private BindingMemberInfo value_member;
  38. private string display_member;
  39. private CurrencyManager data_manager;
  40. protected ListControl ()
  41. {
  42. data_source = null;
  43. value_member = new BindingMemberInfo (string.Empty);
  44. display_member = string.Empty;
  45. data_manager = null;
  46. SetStyle (ControlStyles.StandardClick | ControlStyles.UserPaint, false);
  47. }
  48. #region Events
  49. public event EventHandler DataSourceChanged;
  50. public event EventHandler DisplayMemberChanged;
  51. public event EventHandler SelectedValueChanged;
  52. public event EventHandler ValueMemberChanged;
  53. #endregion // Events
  54. #region Public Properties
  55. [DefaultValue(null)]
  56. [RefreshProperties(RefreshProperties.Repaint)]
  57. [TypeConverter("System.Windows.Forms.Design.DataSourceConverter, " + Consts.AssemblySystem_Design)]
  58. public object DataSource {
  59. get { return data_source; }
  60. set {
  61. if (!(value is IList || value is IListSource)) {
  62. throw new Exception ("Complex DataBinding accepts as a data source " +
  63. "either an IList or an IListSource");
  64. }
  65. if (data_source == value)
  66. return;
  67. data_source = value;
  68. ConnectToDataSource ();
  69. OnDataSourceChanged (EventArgs.Empty);
  70. }
  71. }
  72. [DefaultValue("")]
  73. [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
  74. [TypeConverter("System.Windows.Forms.Design.DataMemberFieldConverter, " + Consts.AssemblySystem_Design)]
  75. public string DisplayMember {
  76. get {
  77. return display_member;
  78. }
  79. set {
  80. if (display_member == value) {
  81. return;
  82. }
  83. display_member = value;
  84. ConnectToDataSource ();
  85. OnDisplayMemberChanged (EventArgs.Empty);
  86. }
  87. }
  88. public abstract int SelectedIndex {
  89. get;
  90. set;
  91. }
  92. [Bindable(BindableSupport.Yes)]
  93. [Browsable(false)]
  94. [DefaultValue(null)]
  95. [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
  96. public object SelectedValue {
  97. get {
  98. if (data_manager == null) {
  99. return null;
  100. }
  101. object item = data_manager.GetItem (SelectedIndex);
  102. object fil = FilterItemOnProperty (item, ValueMember);
  103. return fil;
  104. }
  105. set {
  106. if (data_manager != null) {
  107. PropertyDescriptorCollection col = data_manager.GetItemProperties ();
  108. PropertyDescriptor prop = col.Find (ValueMember, true);
  109. for (int i = 0; i < data_manager.Count; i++) {
  110. if (prop.GetValue (data_manager.GetItem (i)) == value) {
  111. SelectedIndex = i;
  112. return;
  113. }
  114. }
  115. }
  116. }
  117. }
  118. [DefaultValue("")]
  119. [Editor("System.Windows.Forms.Design.DataMemberFieldEditor, " + Consts.AssemblySystem_Design, typeof(System.Drawing.Design.UITypeEditor))]
  120. public string ValueMember {
  121. get { return value_member.BindingMember; }
  122. set {
  123. BindingMemberInfo new_value = new BindingMemberInfo (value);
  124. if (value_member.Equals (new_value)) {
  125. return;
  126. }
  127. value_member = new_value;
  128. if (display_member == string.Empty) {
  129. DisplayMember = value_member.BindingMember;
  130. }
  131. ConnectToDataSource ();
  132. OnValueMemberChanged (EventArgs.Empty);
  133. }
  134. }
  135. #endregion Public Properties
  136. #region Public Methods
  137. protected object FilterItemOnProperty (object item)
  138. {
  139. return FilterItemOnProperty (item, string.Empty);
  140. }
  141. protected object FilterItemOnProperty (object item, string field)
  142. {
  143. if (item == null)
  144. return null;
  145. if (field == null || field == string.Empty)
  146. return item;
  147. PropertyDescriptor prop = null;
  148. if (data_manager != null) {
  149. PropertyDescriptorCollection col = data_manager.GetItemProperties ();
  150. prop = col.Find (field, true);
  151. }
  152. if (prop == null)
  153. return item;
  154. return prop.GetValue (item);
  155. }
  156. public string GetItemText (object item)
  157. {
  158. if (data_manager != null) {
  159. object fil = FilterItemOnProperty (item, DisplayMember);
  160. if (fil != null) {
  161. return fil.ToString ();
  162. }
  163. }
  164. return item.ToString ();
  165. }
  166. protected CurrencyManager DataManager {
  167. get { return data_manager; }
  168. }
  169. // Used only by ListBox to avoid to break Listbox's member signature
  170. protected override bool IsInputKey (Keys keyData)
  171. {
  172. switch (keyData) {
  173. case Keys.Up:
  174. case Keys.Down:
  175. case Keys.PageUp:
  176. case Keys.PageDown:
  177. case Keys.Right:
  178. case Keys.Left:
  179. case Keys.End:
  180. case Keys.Home:
  181. case Keys.ControlKey:
  182. case Keys.Space:
  183. case Keys.ShiftKey:
  184. return true;
  185. default:
  186. return false;
  187. }
  188. }
  189. protected override void OnBindingContextChanged (EventArgs e)
  190. {
  191. base.OnBindingContextChanged (e);
  192. ConnectToDataSource ();
  193. if (DataManager != null) {
  194. SetItemsCore (DataManager.List);
  195. SelectedIndex = DataManager.Position;
  196. }
  197. }
  198. protected virtual void OnDataSourceChanged (EventArgs e)
  199. {
  200. if (DataSourceChanged != null)
  201. DataSourceChanged (this,e);
  202. }
  203. protected virtual void OnDisplayMemberChanged (EventArgs e)
  204. {
  205. if (DisplayMemberChanged != null)
  206. DisplayMemberChanged (this, e);
  207. }
  208. protected virtual void OnSelectedIndexChanged (EventArgs e)
  209. {
  210. if (data_manager == null)
  211. return;
  212. if (data_manager.Position == SelectedIndex)
  213. return;
  214. data_manager.Position = SelectedIndex;
  215. }
  216. protected virtual void OnSelectedValueChanged (EventArgs e)
  217. {
  218. if (SelectedValueChanged != null)
  219. SelectedValueChanged (this, e);
  220. }
  221. protected virtual void OnValueMemberChanged (EventArgs e)
  222. {
  223. if (ValueMemberChanged != null)
  224. ValueMemberChanged (this, e);
  225. }
  226. protected abstract void RefreshItem (int index);
  227. protected virtual void SetItemCore (int index, object value)
  228. {
  229. }
  230. protected abstract void SetItemsCore (IList items);
  231. #endregion Public Methods
  232. #region Private Methods
  233. internal void BindDataItems (IList items)
  234. {
  235. items.Clear ();
  236. if (data_manager != null) {
  237. SetItemsCore (data_manager.List);
  238. }
  239. }
  240. private void ConnectToDataSource ()
  241. {
  242. if (data_source == null) {
  243. data_manager = null;
  244. return;
  245. }
  246. if (BindingContext == null) {
  247. return;
  248. }
  249. data_manager = (CurrencyManager) BindingContext [data_source];
  250. data_manager.PositionChanged += new EventHandler (OnPositionChanged);
  251. }
  252. private void OnPositionChanged (object sender, EventArgs e)
  253. {
  254. SelectedIndex = data_manager.Position;
  255. }
  256. #endregion Private Methods
  257. }
  258. }