Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Custom DataBinding, проблема при завязке на контрол 
V
    Опции темы
sammix
  Дата 12.6.2006, 23:47 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 1.10.2005

Репутация: нет
Всего: 2



Товарищи девелоперы ! Кто нибудь когда-то стыкался с проблемой реализации кастом дата биндинга ?

Код

#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..... 
PM MAIL   Вверх
mr.DUDA
Дата 14.6.2006, 11:26 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


3D-маньяк
****


Профиль
Группа: Экс. модератор
Сообщений: 8244
Регистрация: 27.7.2003
Где: город-герой Минск

Репутация: 110
Всего: 232



Похоже на то, что GetEnumerator() должен вернуть перечислитель простой коллекции (в приведённом коде он возвращает IDictionaryEnumerator, который при проходе foreach-ем в Value содержит DictionaryEntry). Можно, к примеру, переделать код вот так: m_items.Values.GetEnumerator() 


--------------------
user posted image
PM MAIL WWW   Вверх
sammix
Дата 16.6.2006, 18:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 31
Регистрация: 1.10.2005

Репутация: нет
Всего: 2



Точно проблема была с энумератором.
Спасибо  smile  
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0870 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.