Как работать с 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
}