Как работать с GetDataPresent, чтобы он мог принимать все производные типы

Я использую drgevent.Data.GetDataPresent, чтобы определить, является ли перетаскиваемый компонент приемлемым или нет.

У меня есть проблема, которая заключается в том, что я хочу принять определенный тип скажем SomeType и все типы, производные от него. Кажется GetDataPresent не поддерживает такое требование.

Любая идея?

3 ответа

Решение

Только не используйте GetDataPresent(), это шаблон, но вы можете сделать это по-своему. На самом деле получить объект и проверить, довольны ли вы его типом:

    protected override void OnDragEnter(DragEventArgs drgevent) {
        var obj = drgevent.Data.GetData(drgevent.Data.GetFormats()[0]);
        if (typeof(Base).IsAssignableFrom(obj.GetType())) {
            drgevent.Effect = DragDropEffects.Copy;
        }
    }

Где Base - это имя базового класса. Хотя использование GetFormats() выглядит странно, этот подход гарантированно сработает, поскольку перетаскивание объекта.NET создает только один формат - отображаемое имя типа объекта. По этой же причине GetDataPresent не может работать с производными объектами.

Я уже ответил на аналогичный вопрос ранее: C# Drag and Drop - e.Data.GetData с использованием базового класса

Что вы можете сделать, это создать контейнерный класс, который содержит данные, которые вы перетаскиваете. И затем в GetDataPresent вы проверяете тип класса контейнера, и если он присутствует, вы можете прочитать элемент содержимого, который содержит фактический экземпляр ваших данных.

Вот быстрый пример, если ваш базовый тип - DragDropBaseData, вы можете создать следующий класс DragDropInfo.

public class DragDropInfo 
{ 
  public DragDropBaseData Value { get; private set; } 

  public DragDropInfo(DragDropBaseData value) 
  { 
    this.Value= value; 
  } 
}

И затем перетаскивание может быть инициировано следующим образом, где DrafDropDerivedData является классом, производным от DragDropBaseData.

DoDragDrop(new DragDropInfo(new DragDropDerivedData() ), DragDropEffects.All); 

И вы можете получить доступ к данным в событиях перетаскивания, используя следующие

e.Data.GetData(typeof(DragDropInfo)); 

У меня была похожая проблема. Я хочу, чтобы он использовал DragDrop только с интерфейсами, которые не работают в эфире. Поэтому я помещаю свои данные в массив объектов.

      DoDragDrop(_dragDropSource, new[] { _dragDropSource.DataContext }, DragDropEffects.Move);

if (((object[]) e.Data.GetData(typeof(object[])))?[0] is ICatTreeViewGroup group) {
  // do something with a group
}
Другие вопросы по тегам