Как создать сопоставимый образ

#c# #datagridview #bindinglist

#c# #datagridview #список привязок

Вопрос:

У меня есть a DataGridView , который был привязан к общему BindingList . Я хочу иметь возможность применять сортировку и поиск по столбцам типа DataGridViewImageColumn . Основная идея состоит в том, чтобы сохранить имя в изображении Tag и использовать его для сортировки и поиска.Как я могу это сделать?

Кажется, это можно сделать несколькими способами:

  1. Создание нового класса, наследующего System.Drawing.Image и делающего его сопоставимым.
    • Image это абстрактный класс, и если я унаследую его (а также IComparable интерфейс), я столкнусь с этим сообщением об ошибке: Тип ‘System.Рисование.У Image’ не определены конструкторы. В чем здесь проблема? Image — это abstract не sealed класс, но он не позволяет мне наследовать его!
  2. Используя защищенный ApplySortCore метод переопределения унаследованного класса от BindingList<T> .

    • Этот метод выглядит так:

       class MyBindingList<T> : BindingList<T>
      {
          ...
          protected override void ApplySortCore(PropertyDescriptor prop,
                                                ListSortDirection direction)
          {
              if (prop.PropertyType.Equals(typeof(Image)))
              {
                  /* I have no idea! */
              }
          }
      }
        
  3. Создание нового DataGridViewColumn наследования от DataGridViewImageColumn .
    • Это не кажется простым и может быть использовано, если другие идеи непригодны.

Заранее спасибо

Ответ №1:

Создайте класс (X), который инкапсулирует System.Рисование. Изображение ImageAlias строковое свойство. Привяжите свой столбец изображения к X.Image и выполните поиск по X.ImageAlias.

Извините, но у меня нет инструмента для программирования, чтобы привести пример, но это основная идея.

Надеюсь, это поможет.

Комментарии:

1. Хорошая идея! Но мне нужна реализация — спасибо

2. Я создал класс с именем ComparableImage , унаследованным от IComparable , и добавил два свойства, как вы упомянули выше. Теперь, если я привяжусь DataGridViewImageColumn к свойству типа ComparableImage , оно сможет сортировать, но не сможет отображать инкапсулированное изображение. (Я попытался обработать DataError событие, передав внутреннее изображение в значение ячейки, но механизм привязки данных предотвращает это. Потому что я пытался установить изображение в свойство типа ComparableImage .) Если я привязываюсь ComparableImage.Image к DGV, он не может обнаружить класс владельца и поэтому не может его отсортировать. Укажите, пожалуйста, какой-нибудь код.

Ответ №2:

Я нашел способ!


MyBindingList

 class MyBindingList<T> : BindingList<T>
{
    ...
    protected override void ApplySortCore(PropertyDescriptor prop,
                                          ListSortDirection direction)
    {
        if (prop.PropertyType.Equals(typeof(Image)))
        {
            _SortPropertyCore = prop;
            _SortDirectionCore = direction;

            var items = this.Items;
            Func<T, object> func =
                new Func<T, object>(t => (prop.GetValue(t) as Image).Tag);

            switch (direction)
            {
                case ListSortDirection.Ascending:
                    items = items.OrderBy(func).ToList();
                    break;

                case ListSortDirection.Descending:
                    items = items.OrderByDescending(func).ToList();
                    break;
            }

            ResetItems(items as List<T>);
            ResetBindings();
        }
        else
        {
            ...
        }
    }

    private void ResetItems(List<T> items)
    {
        base.ClearItems();

        for (int itemIndex = 0; itemIndex < items.Count; itemIndex  )
        {
            base.InsertItem(itemIndex, items[itemIndex]);
        }
    }
}
  

MyDataObject

 class MyDataObject : INotifyPropertyChanged
{
    ...

    public Image MyProp
    {
        get
        {
            return CreateComparableImage(myImage, "myImage");
        }
    }

    private Image CreateComparableImage(Image image, string alias)
    {
        Image taggedImage = new Bitmap(image);
        taggedImage.Tag = alias;

        return taggedImage;
    }
}
  

Форма

 class MyForm : Form
{
    ...

    void BindDGV()
    {
        dataGridView1.Columns["myColumnName"].DataPropertyName = "MyProp";
        dataGridView1.DataSource = MyBindingList<MyDataObject>(...);
    }
}