/******************************************************************************* * Copyright(c) 2014 DongkeSoft All rights reserved. / Confidential * 类的信息: * 1.程序名称:ListSelectionWrapper.cs * 2.功能描述:类文件 * 编辑履历: * 作者 日期 版本 修改内容 * 陈晓野 2014/09/29 1.00 新建 *******************************************************************************/ using System; using System.Collections; using System.Collections.Generic; using System.Reflection; using System.ComponentModel; namespace Dongke.IBOSS.PRD.Basics.BaseControls { /// /// Maintains an additional "Selected" & "Count" value for each item in a List. /// Useful in the CheckBoxComboBox. It holds a reference to the List[Index] Item and /// whether it is selected or not. /// It also caters for a Count, if needed. /// /// public class ListSelectionWrapper : List> { #region CONSTRUCTOR ///// ///// No property on the object is specified for display purposes, so simple ToString() operation ///// will be performed. And no Counts will be displayed ///// //public ListSelectionWrapper(IEnumerable source) : this(source, false) { } ///// ///// No property on the object is specified for display purposes, so simple ToString() operation ///// will be performed. ///// //private ListSelectionWrapper(IEnumerable source, bool showCounts) // : base() //{ // _Source = source; // _ShowCounts = showCounts; // if (_Source is IBindingList) // ((IBindingList)_Source).ListChanged += new ListChangedEventHandler(ListSelectionWrapper_ListChanged); // Populate(); //} ///// ///// A Display "Name" property is specified. ToString() will not be performed on items. ///// This is specifically useful on DataTable implementations, or where PropertyDescriptors are used to read the values. ///// If a PropertyDescriptor is not found, a Property will be used. ///// //public ListSelectionWrapper(IEnumerable source, string usePropertyAsDisplayName) : this(source, false, usePropertyAsDisplayName) { } ///// ///// A Display "Name" property is specified. ToString() will not be performed on items. ///// This is specifically useful on DataTable implementations, or where PropertyDescriptors are used to read the values. ///// If a PropertyDescriptor is not found, a Property will be used. ///// //public ListSelectionWrapper(IEnumerable source, bool showCounts, string usePropertyAsDisplayName) // : this(source, showCounts) //{ // _DisplayNameProperty = usePropertyAsDisplayName; //} public ListSelectionWrapper(IEnumerable source, string usePropertyAsDisplayName, string valueProperty) : base() { _Source = source; _ShowCounts = false; _DisplayNameProperty = usePropertyAsDisplayName; _ValueProperty = valueProperty; if (_Source is IBindingList) ((IBindingList)_Source).ListChanged += new ListChangedEventHandler(ListSelectionWrapper_ListChanged); Populate(); } #endregion #region PRIVATE PROPERTIES /// /// Is a Count indicator used. /// private bool _ShowCounts; /// /// The original List of values wrapped. A "Selected" and possibly "Count" functionality is added. /// private IEnumerable _Source; /// /// Used to indicate NOT to use ToString(), but read this property instead as a display value. /// private string _DisplayNameProperty = null; private string _ValueProperty = null; #endregion #region PUBLIC PROPERTIES /// /// When specified, indicates that ToString() should not be performed on the items. /// This property will be read instead. /// This is specifically useful on DataTable implementations, where PropertyDescriptors are used to read the values. /// public string DisplayNameProperty { get { return _DisplayNameProperty; } set { _DisplayNameProperty = value; } } public string ValueProperty { get { return _ValueProperty; } set { _ValueProperty = value; } } /// /// Builds a concatenation list of selected items in the list. /// public string SelectedNames { get { string Text = ""; foreach (ObjectSelectionWrapper Item in this) if (Item.Selected) Text += ( string.IsNullOrEmpty(Text) ? String.Format("\"{0}\"", Item.Name) : String.Format(" & \"{0}\"", Item.Name)); return Text; } } public TValue[] SelectedValues { get { List Values = new List(); foreach (ObjectSelectionWrapper Item in this) if (Item.Selected) Values.Add(Item.Value); return Values.ToArray(); } } /// /// Indicates whether the Item display value (Name) should include a count. /// public bool ShowCounts { get { return _ShowCounts; } set { _ShowCounts = value; } } #endregion #region HELPER MEMBERS /// /// Reset all counts to zero. /// public void ClearCounts() { foreach (ObjectSelectionWrapper Item in this) Item.Count = 0; } /// /// Creates a ObjectSelectionWrapper item. /// Note that the constructor signature of sub classes classes are important. /// /// /// private ObjectSelectionWrapper CreateSelectionWrapper(IEnumerator Object) { Type[] Types = new Type[] { typeof(TItem), this.GetType() }; ConstructorInfo CI = typeof(ObjectSelectionWrapper).GetConstructor(Types); if (CI == null) throw new Exception(String.Format( "The selection wrapper class {0} must have a constructor with ({1} Item, {2} Container) parameters.", typeof(ObjectSelectionWrapper), typeof(TItem), this.GetType())); object[] parameters = new object[] { Object.Current, this }; object result = CI.Invoke(parameters); return (ObjectSelectionWrapper)result; } public ObjectSelectionWrapper FindObjectWithItem(TItem Object) { return Find(new Predicate>( delegate(ObjectSelectionWrapper target) { return target.Item.Equals(Object); })); } public ObjectSelectionWrapper FindObjectWithValue(TValue Object) { return Find(new Predicate>( delegate(ObjectSelectionWrapper target) { return target.Value.Equals(Object); })); } /* public TSelectionWrapper FindObjectWithKey(object key) { return FindObjectWithKey(new object[] { key }); } public TSelectionWrapper FindObjectWithKey(object[] keys) { return Find(new Predicate( delegate(TSelectionWrapper target) { return ReflectionHelper.CompareKeyValues( ReflectionHelper.GetKeyValuesFromObject(target.Item, target.Item.TableInfo), keys); })); } public object[] GetArrayOfSelectedKeys() { List List = new List(); foreach (TSelectionWrapper Item in this) if (Item.Selected) { if (Item.Item.TableInfo.KeyProperties.Length == 1) List.Add(ReflectionHelper.GetKeyValueFromObject(Item.Item, Item.Item.TableInfo)); else List.Add(ReflectionHelper.GetKeyValuesFromObject(Item.Item, Item.Item.TableInfo)); } return List.ToArray(); } public T[] GetArrayOfSelectedKeys() { List List = new List(); foreach (TSelectionWrapper Item in this) if (Item.Selected) { if (Item.Item.TableInfo.KeyProperties.Length == 1) List.Add((T)ReflectionHelper.GetKeyValueFromObject(Item.Item, Item.Item.TableInfo)); else throw new LibraryException("This generator only supports single value keys."); // List.Add((T)ReflectionHelper.GetKeyValuesFromObject(Item.Item, Item.Item.TableInfo)); } return List.ToArray(); } */ private void Populate() { Clear(); /* for(int Index = 0; Index <= _Source.Count -1; Index++) Add(CreateSelectionWrapper(_Source[Index])); */ IEnumerator Enumerator = _Source.GetEnumerator(); if (Enumerator != null) while (Enumerator.MoveNext()) Add(CreateSelectionWrapper(Enumerator)); } #endregion #region EVENT HANDLERS private void ListSelectionWrapper_ListChanged(object sender, ListChangedEventArgs e) { switch (e.ListChangedType) { case ListChangedType.ItemAdded: Add(CreateSelectionWrapper((IEnumerator)((IBindingList)_Source)[e.NewIndex])); break; case ListChangedType.ItemDeleted: Remove(FindObjectWithItem((TItem)((IBindingList)_Source)[e.OldIndex])); break; case ListChangedType.Reset: Populate(); break; } } #endregion } }