Товарищи девелоперы ! Кто нибудь когда-то стыкался с проблемой реализации кастом дата биндинга ? Код | #region file using directives using System; using System.ComponentModel; using System.Collections; using System.Reflection; #endregion
namespace KTP.Business.Primitivies.Collections { /// <summary> /// /// </summary> public abstract class BindingCollectionBase : IBindingList { #region Class members /// <summary> /// hash: Primary Key - to - Item /// </summary> private Hashtable m_items; /// <summary> /// Stored order of items adding/inserting into collection. /// </summary> private ArrayList m_itemsKey; /// <summary> /// /// </summary> private bool m_bQuiet; /// <summary> /// /// </summary> private ListSortDirection m_direction; /// <summary> /// /// </summary> private PropertyDescriptor m_sortProperty; /// <summary> /// /// </summary> private bool m_bSort; /// <summary> /// /// </summary> private int m_version; #endregion
#region Class properties /// <summary> /// Gets or sets item from collection by it order index. /// </summary> /// <param name="id">Order Index of item in collection</param> object IList.this[ int id ] { get { return m_items[ m_itemsKey[ id ] ]; } set { object obj = (( IList )this)[ id ];
if( obj != value ) { obj = value; RaiseListChanged( ListChangedType.ItemChanged ); } } } /// <summary> /// /// </summary> public bool IsSynchronized { get { return m_items.IsSynchronized; } } /// <summary> /// /// </summary> public PropertyDescriptor SortProperty { get { return m_sortProperty; } } /// <summary> /// Gets or Sets version of collection. This property used for controlling /// live cycle of enumerators. /// </summary> protected internal int Version { get { return m_version; } set { m_version = value; } } /// <summary> /// Get hash table that contains pair primary_key-to-item. /// </summary> protected Hashtable InnerHash { get { return m_items; } } /// <summary> /// /// </summary> protected abstract string PrimaryIndexPropertyName{ get; } #endregion
#region Class events /// <summary> /// /// </summary> public event ListChangedEventHandler ListChanged; #endregion
#region Class Initialize/Finalize methods /// <summary> /// /// </summary> protected BindingCollectionBase() { m_items = new Hashtable(); m_itemsKey = new ArrayList(); m_direction = ListSortDirection.Ascending; } #endregion
/// <summary> /// /// </summary> /// <returns></returns> IEnumerator IEnumerable.GetEnumerator() { return m_items.GetEnumerator(); } #endregion /// <summary> /// IComparer hierarchy class for Descending type sorting /// </summary> internal class ComparerDescending : IComparer { #region Class members /// <summary> /// /// </summary> private static readonly ComparerDescending _default = new ComparerDescending(); #endregion
#region Class static properties /// <summary> /// /// </summary> public static IComparer Default { get { return _default; } }
#endregion
#region Class Initialize/Finalize methods /// <summary> /// /// </summary> private ComparerDescending() { } #endregion
#region IComparer Members /// <summary> /// /// </summary> /// <param name="x"></param> /// <param name="y"></param> /// <returns></returns> public int Compare( object x, object y ) { return -CaseInsensitiveComparer.DefaultInvariant.Compare( x, y ); } #endregion }
/// <summary> /// /// </summary> public class CollectionPropertyDescriptor : PropertyDescriptor { #region Class members /// <summary> /// /// </summary> private PropertyInfo m_info; /// <summary> /// /// </summary> private Type m_collectionType; #endregion
#region Class properties /// <summary> /// /// </summary> public override Type ComponentType { get { return m_collectionType; } }
/// <summary> /// /// </summary> public override Type PropertyType { get { return m_info.PropertyType; } } /// <summary> /// /// </summary> public override bool IsReadOnly { get { return true; } } #endregion
#region Class Initialize/Finalize methods /// <summary> /// Create property description for BindingCollection classes /// </summary> /// <param name="memberName"> Name of member </param> /// <param name="type"> type of collection items </param> public CollectionPropertyDescriptor( string memberName, Type type ) : base( memberName, null ) { if( null == memberName ) throw new ArgumentNullException( "memberName" );
if( 0 == memberName.Length ) throw new ArgumentException( "memberName - string can not be empty" );
m_collectionType = type; m_info = type.GetProperty( this.Name );
if( m_info == null ) throw new ArgumentNullException( "Vacation type doesn't have '" + memberName + "' property." ); } #endregion
#region Class overrides /// <summary> /// /// </summary> /// <param name="component"></param> /// <returns></returns> public override bool ShouldSerializeValue( object component ) { return false; } /// <summary> /// /// </summary> /// <param name="component"></param> public override void ResetValue( object component ) { // do nothing } /// <summary> /// /// </summary> /// <param name="component"></param> /// <returns></returns> public override bool CanResetValue( object component ) { return false; } /// <summary> /// Get value of property by component Vacation object /// </summary> /// <param name="component"></param> /// <returns> value of </returns> public override object GetValue( object component ) { object result = null;
//if( component is ComponentType ) { result = m_collectionType.GetProperty( this.Name ).GetValue( component, null ); }
return result; } /// <summary> /// /// </summary> /// <param name="component"></param> /// <param name="value"></param> public override void SetValue( object component, object value ) { // do nothing } #endregion } }
|
код я немного сократил, а то он немножко большой. Как видете класик имплементит интерфейс IBindingList. Коллекция была переработана так, чтобы по индексатору был доступ к елементам по их ID ( данные берутся с БД ). Соответсвенно чтобы получить елемент с 0 индексом ( не ID ) нужно приводить переменную к IList. Проблема такова. Когда я соединяю колекцию с ComboBox через DataSource, контрол не правильно выгребает данные. Вместо конкретного типа елемента, ему выкидывается DictionaryEntry с хеш таблицы. При попытке такой же завязки на мой собственный комбобокс, была такая же проблема. Но она решилась путём замены в коде разборки данных foreach на for. Но здесь проблема не решается. Я пока так и не понял как же подсунуть вместо DictionaryEntry, свой тип. Кстати интересно что при ручном дебаге, через foreach всё ок. А вот ComboBox.....
|