DragAndDrop core
This commit is contained in:
713
Lattice.Core.DragDrop/Utilities/AsyncDragDropUtilities.cs
Normal file
713
Lattice.Core.DragDrop/Utilities/AsyncDragDropUtilities.cs
Normal file
@@ -0,0 +1,713 @@
|
||||
using Lattice.Core.DragDrop.Abstractions;
|
||||
using Lattice.Core.DragDrop.Enums;
|
||||
using Lattice.Core.DragDrop.Models;
|
||||
|
||||
namespace Lattice.Core.DragDrop.Utilities;
|
||||
|
||||
/// <summary>
|
||||
/// Предоставляет утилитарные методы и фабричные методы для работы с системой перетаскивания с поддержкой async.
|
||||
/// </summary>
|
||||
public static class AsyncDragDropUtilities
|
||||
{
|
||||
/// <summary>
|
||||
/// Создает асинхронную реализацию источника перетаскивания.
|
||||
/// </summary>
|
||||
public static IAsyncDragSource CreateAsyncDragSource(
|
||||
Func<Task<object>> dataProviderAsync,
|
||||
Func<Task<bool>>? canDragAsync = null,
|
||||
Func<DragInfo, DragDropEffects, Task>? onCompletedAsync = null,
|
||||
Func<DragInfo, Task>? onCancelledAsync = null)
|
||||
{
|
||||
return new AsyncDragSourceWrapper(dataProviderAsync, canDragAsync, onCompletedAsync, onCancelledAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает асинхронную реализацию цели сброса.
|
||||
/// </summary>
|
||||
public static IAsyncDropTarget CreateAsyncDropTarget(
|
||||
Func<DropInfo, Task<bool>>? canAcceptAsync = null,
|
||||
Func<DropInfo, Task>? onDragOverAsync = null,
|
||||
Func<DropInfo, Task>? onDropAsync = null,
|
||||
Func<Task>? onDragLeaveAsync = null)
|
||||
{
|
||||
return new AsyncDropTargetWrapper(canAcceptAsync, onDragOverAsync, onDropAsync, onDragLeaveAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает адаптер для преобразования синхронного источника в асинхронный.
|
||||
/// </summary>
|
||||
public static IAsyncDragSource CreateAsyncAdapter(IDragSource syncSource)
|
||||
{
|
||||
return new SyncToAsyncDragSourceAdapter(syncSource);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает адаптер для преобразования синхронной цели в асинхронную.
|
||||
/// </summary>
|
||||
public static IAsyncDropTarget CreateAsyncAdapter(IDropTarget syncTarget)
|
||||
{
|
||||
return new SyncToAsyncDropTargetAdapter(syncTarget);
|
||||
}
|
||||
|
||||
#region Обертки-реализации
|
||||
|
||||
/// <summary>
|
||||
/// Обертка для создания асинхронного источника перетаскивания.
|
||||
/// </summary>
|
||||
private sealed class AsyncDragSourceWrapper : IAsyncDragSource
|
||||
{
|
||||
private readonly Func<Task<object>> _dataProviderAsync;
|
||||
private readonly Func<Task<bool>>? _canDragAsync;
|
||||
private readonly Func<DragInfo, DragDropEffects, Task>? _onCompletedAsync;
|
||||
private readonly Func<DragInfo, Task>? _onCancelledAsync;
|
||||
|
||||
public AsyncDragSourceWrapper(
|
||||
Func<Task<object>> dataProviderAsync,
|
||||
Func<Task<bool>>? canDragAsync = null,
|
||||
Func<DragInfo, DragDropEffects, Task>? onCompletedAsync = null,
|
||||
Func<DragInfo, Task>? onCancelledAsync = null)
|
||||
{
|
||||
_dataProviderAsync = dataProviderAsync ?? throw new ArgumentNullException(nameof(dataProviderAsync));
|
||||
_canDragAsync = canDragAsync;
|
||||
_onCompletedAsync = onCompletedAsync;
|
||||
_onCancelledAsync = onCancelledAsync;
|
||||
}
|
||||
|
||||
public async Task<(bool CanStart, DragInfo? DragInfo)> CanStartDragAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Проверяем, может ли начаться перетаскивание
|
||||
if (_canDragAsync != null)
|
||||
{
|
||||
var canDrag = await _canDragAsync().ConfigureAwait(false);
|
||||
if (!canDrag)
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
// Получаем данные
|
||||
var data = await _dataProviderAsync().ConfigureAwait(false);
|
||||
if (data == null)
|
||||
return (false, null);
|
||||
|
||||
// Создаем информацию о перетаскивании
|
||||
var dragInfo = DragDropUtilities.CreateDragInfo(
|
||||
data,
|
||||
Geometry.Point.Zero,
|
||||
DragDropEffects.Copy | DragDropEffects.Move,
|
||||
this);
|
||||
|
||||
return (true, dragInfo);
|
||||
}
|
||||
catch
|
||||
{
|
||||
return (false, null);
|
||||
}
|
||||
}
|
||||
|
||||
public Task<bool> StartDragAsync(DragInfo dragInfo)
|
||||
{
|
||||
// Базовая реализация всегда разрешает начало
|
||||
return Task.FromResult(true);
|
||||
}
|
||||
|
||||
public async Task DragCompletedAsync(DragInfo dragInfo, DragDropEffects effects)
|
||||
{
|
||||
if (_onCompletedAsync != null)
|
||||
{
|
||||
await _onCompletedAsync(dragInfo, effects).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DragCancelledAsync(DragInfo dragInfo)
|
||||
{
|
||||
if (_onCancelledAsync != null)
|
||||
{
|
||||
await _onCancelledAsync(dragInfo).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
|
||||
#region Синхронная реализация (для IDragSource)
|
||||
|
||||
public bool CanStartDrag(out DragInfo? dragInfo)
|
||||
{
|
||||
// Для синхронного вызова используем Task.Result
|
||||
var result = Task.Run(() => CanStartDragAsync()).GetAwaiter().GetResult();
|
||||
dragInfo = result.DragInfo;
|
||||
return result.CanStart;
|
||||
}
|
||||
|
||||
public bool StartDrag(DragInfo dragInfo)
|
||||
{
|
||||
return Task.Run(() => StartDragAsync(dragInfo)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public void DragCompleted(DragInfo dragInfo, DragDropEffects effects)
|
||||
{
|
||||
Task.Run(() => DragCompletedAsync(dragInfo, effects)).Wait();
|
||||
}
|
||||
|
||||
public void DragCancelled(DragInfo dragInfo)
|
||||
{
|
||||
Task.Run(() => DragCancelledAsync(dragInfo)).Wait();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Обертка для создания асинхронной цели сброса.
|
||||
/// </summary>
|
||||
private sealed class AsyncDropTargetWrapper : IAsyncDropTarget
|
||||
{
|
||||
private readonly Func<DropInfo, Task<bool>>? _canAcceptAsync;
|
||||
private readonly Func<DropInfo, Task>? _onDragOverAsync;
|
||||
private readonly Func<DropInfo, Task>? _onDropAsync;
|
||||
private readonly Func<Task>? _onDragLeaveAsync;
|
||||
|
||||
public AsyncDropTargetWrapper(
|
||||
Func<DropInfo, Task<bool>>? canAcceptAsync = null,
|
||||
Func<DropInfo, Task>? onDragOverAsync = null,
|
||||
Func<DropInfo, Task>? onDropAsync = null,
|
||||
Func<Task>? onDragLeaveAsync = null)
|
||||
{
|
||||
_canAcceptAsync = canAcceptAsync;
|
||||
_onDragOverAsync = onDragOverAsync;
|
||||
_onDropAsync = onDropAsync;
|
||||
_onDragLeaveAsync = onDragLeaveAsync;
|
||||
}
|
||||
|
||||
public async Task<bool> CanAcceptDropAsync(DropInfo dropInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_canAcceptAsync != null)
|
||||
{
|
||||
return await _canAcceptAsync(dropInfo).ConfigureAwait(false);
|
||||
}
|
||||
return true; // По умолчанию принимаем все
|
||||
}
|
||||
catch
|
||||
{
|
||||
return false; // При ошибке не принимаем
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DragOverAsync(DropInfo dropInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_onDragOverAsync != null)
|
||||
{
|
||||
await _onDragOverAsync(dropInfo).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Игнорируем ошибки в обработчике
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DropAsync(DropInfo dropInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_onDropAsync != null)
|
||||
{
|
||||
await _onDropAsync(dropInfo).ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Игнорируем ошибки в обработчике
|
||||
}
|
||||
}
|
||||
|
||||
public async Task DragLeaveAsync()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (_onDragLeaveAsync != null)
|
||||
{
|
||||
await _onDragLeaveAsync().ConfigureAwait(false);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Игнорируем ошибки в обработчике
|
||||
}
|
||||
}
|
||||
|
||||
#region Синхронная реализация (для IDropTarget)
|
||||
|
||||
public bool CanAcceptDrop(DropInfo dropInfo)
|
||||
{
|
||||
return Task.Run(() => CanAcceptDropAsync(dropInfo)).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
public void DragOver(DropInfo dropInfo)
|
||||
{
|
||||
Task.Run(() => DragOverAsync(dropInfo)).Wait();
|
||||
}
|
||||
|
||||
public void Drop(DropInfo dropInfo)
|
||||
{
|
||||
Task.Run(() => DropAsync(dropInfo)).Wait();
|
||||
}
|
||||
|
||||
public void DragLeave()
|
||||
{
|
||||
Task.Run(DragLeaveAsync).Wait();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Адаптер для преобразования синхронного источника в асинхронный.
|
||||
/// </summary>
|
||||
private sealed class SyncToAsyncDragSourceAdapter : IAsyncDragSource
|
||||
{
|
||||
private readonly IDragSource _syncSource;
|
||||
|
||||
public SyncToAsyncDragSourceAdapter(IDragSource syncSource)
|
||||
{
|
||||
_syncSource = syncSource ?? throw new ArgumentNullException(nameof(syncSource));
|
||||
}
|
||||
|
||||
public async Task<(bool CanStart, DragInfo? DragInfo)> CanStartDragAsync()
|
||||
{
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
var canStart = _syncSource.CanStartDrag(out var dragInfo);
|
||||
return (canStart, dragInfo);
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> StartDragAsync(DragInfo dragInfo)
|
||||
{
|
||||
return await Task.Run(() => _syncSource.StartDrag(dragInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragCompletedAsync(DragInfo dragInfo, DragDropEffects effects)
|
||||
{
|
||||
await Task.Run(() => _syncSource.DragCompleted(dragInfo, effects)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragCancelledAsync(DragInfo dragInfo)
|
||||
{
|
||||
await Task.Run(() => _syncSource.DragCancelled(dragInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#region Синхронная реализация (делегируем синхронному источнику)
|
||||
|
||||
public bool CanStartDrag(out DragInfo? dragInfo)
|
||||
{
|
||||
return _syncSource.CanStartDrag(out dragInfo);
|
||||
}
|
||||
|
||||
public bool StartDrag(DragInfo dragInfo)
|
||||
{
|
||||
return _syncSource.StartDrag(dragInfo);
|
||||
}
|
||||
|
||||
public void DragCompleted(DragInfo dragInfo, DragDropEffects effects)
|
||||
{
|
||||
_syncSource.DragCompleted(dragInfo, effects);
|
||||
}
|
||||
|
||||
public void DragCancelled(DragInfo dragInfo)
|
||||
{
|
||||
_syncSource.DragCancelled(dragInfo);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Адаптер для преобразования синхронной цели в асинхронную.
|
||||
/// </summary>
|
||||
private sealed class SyncToAsyncDropTargetAdapter : IAsyncDropTarget
|
||||
{
|
||||
private readonly IDropTarget _syncTarget;
|
||||
|
||||
public SyncToAsyncDropTargetAdapter(IDropTarget syncTarget)
|
||||
{
|
||||
_syncTarget = syncTarget ?? throw new ArgumentNullException(nameof(syncTarget));
|
||||
}
|
||||
|
||||
public async Task<bool> CanAcceptDropAsync(DropInfo dropInfo)
|
||||
{
|
||||
return await Task.Run(() => _syncTarget.CanAcceptDrop(dropInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragOverAsync(DropInfo dropInfo)
|
||||
{
|
||||
await Task.Run(() => _syncTarget.DragOver(dropInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DropAsync(DropInfo dropInfo)
|
||||
{
|
||||
await Task.Run(() => _syncTarget.Drop(dropInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragLeaveAsync()
|
||||
{
|
||||
await Task.Run(() => _syncTarget.DragLeave()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#region Синхронная реализация (делегируем синхронной цели)
|
||||
|
||||
public bool CanAcceptDrop(DropInfo dropInfo)
|
||||
{
|
||||
return _syncTarget.CanAcceptDrop(dropInfo);
|
||||
}
|
||||
|
||||
public void DragOver(DropInfo dropInfo)
|
||||
{
|
||||
_syncTarget.DragOver(dropInfo);
|
||||
}
|
||||
|
||||
public void Drop(DropInfo dropInfo)
|
||||
{
|
||||
_syncTarget.Drop(dropInfo);
|
||||
}
|
||||
|
||||
public void DragLeave()
|
||||
{
|
||||
_syncTarget.DragLeave();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Утилитарные методы
|
||||
|
||||
/// <summary>
|
||||
/// Выполняет асинхронную операцию с таймаутом.
|
||||
/// </summary>
|
||||
public static async Task<T> ExecuteWithTimeoutAsync<T>(
|
||||
Task<T> task,
|
||||
TimeSpan timeout,
|
||||
T defaultValue = default!)
|
||||
{
|
||||
if (timeout <= TimeSpan.Zero)
|
||||
return await task.ConfigureAwait(false);
|
||||
|
||||
var delayTask = Task.Delay(timeout);
|
||||
var completedTask = await Task.WhenAny(task, delayTask).ConfigureAwait(false);
|
||||
|
||||
if (completedTask == delayTask)
|
||||
{
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
return await task.ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выполняет асинхронную операцию с таймаутом.
|
||||
/// </summary>
|
||||
public static async Task<bool> ExecuteWithTimeoutAsync(
|
||||
Task task,
|
||||
TimeSpan timeout)
|
||||
{
|
||||
if (timeout <= TimeSpan.Zero)
|
||||
{
|
||||
await task.ConfigureAwait(false);
|
||||
return true;
|
||||
}
|
||||
|
||||
var delayTask = Task.Delay(timeout);
|
||||
var completedTask = await Task.WhenAny(task, delayTask).ConfigureAwait(false);
|
||||
|
||||
return completedTask == task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Выполняет асинхронную операцию с таймаутом и обработкой ошибок.
|
||||
/// </summary>
|
||||
public static async Task<T?> ExecuteSafeWithTimeoutAsync<T>(
|
||||
Task<T> task,
|
||||
TimeSpan timeout,
|
||||
Func<Exception, T?> errorHandler = null) where T : class
|
||||
{
|
||||
try
|
||||
{
|
||||
if (timeout <= TimeSpan.Zero)
|
||||
return await task.ConfigureAwait(false);
|
||||
|
||||
var delayTask = Task.Delay(timeout);
|
||||
var completedTask = await Task.WhenAny(task, delayTask).ConfigureAwait(false);
|
||||
|
||||
if (completedTask == delayTask)
|
||||
{
|
||||
return default;
|
||||
}
|
||||
|
||||
return await task.ConfigureAwait(false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return errorHandler?.Invoke(ex) ?? default;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает комбинированный источник из синхронного и асинхронного.
|
||||
/// </summary>
|
||||
public static IAsyncDragSource Combine(
|
||||
IDragSource syncSource,
|
||||
IAsyncDragSource asyncSource,
|
||||
bool preferAsync = true)
|
||||
{
|
||||
return new CombinedDragSource(syncSource, asyncSource, preferAsync);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Создает комбинированную цель из синхронной и асинхронной.
|
||||
/// </summary>
|
||||
public static IAsyncDropTarget Combine(
|
||||
IDropTarget syncTarget,
|
||||
IAsyncDropTarget asyncTarget,
|
||||
bool preferAsync = true)
|
||||
{
|
||||
return new CombinedDropTarget(syncTarget, asyncTarget, preferAsync);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Комбинированные реализации
|
||||
|
||||
/// <summary>
|
||||
/// Комбинированный источник, поддерживающий как синхронный, так и асинхронный API.
|
||||
/// </summary>
|
||||
private sealed class CombinedDragSource : IAsyncDragSource
|
||||
{
|
||||
private readonly IDragSource _syncSource;
|
||||
private readonly IAsyncDragSource _asyncSource;
|
||||
private readonly bool _preferAsync;
|
||||
|
||||
public CombinedDragSource(IDragSource syncSource, IAsyncDragSource asyncSource, bool preferAsync)
|
||||
{
|
||||
_syncSource = syncSource ?? throw new ArgumentNullException(nameof(syncSource));
|
||||
_asyncSource = asyncSource ?? throw new ArgumentNullException(nameof(asyncSource));
|
||||
_preferAsync = preferAsync;
|
||||
}
|
||||
|
||||
public async Task<(bool CanStart, DragInfo? DragInfo)> CanStartDragAsync()
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _asyncSource.CanStartDragAsync().ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
// Используем синхронную версию в отдельной задаче
|
||||
return await Task.Run(() =>
|
||||
{
|
||||
var canStart = _syncSource.CanStartDrag(out var dragInfo);
|
||||
return (canStart, dragInfo);
|
||||
}).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task<bool> StartDragAsync(DragInfo dragInfo)
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _asyncSource.StartDragAsync(dragInfo).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.Run(() => _syncSource.StartDrag(dragInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragCompletedAsync(DragInfo dragInfo, DragDropEffects effects)
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _asyncSource.DragCompletedAsync(dragInfo, effects).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Run(() => _syncSource.DragCompleted(dragInfo, effects)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragCancelledAsync(DragInfo dragInfo)
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _asyncSource.DragCancelledAsync(dragInfo).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Run(() => _syncSource.DragCancelled(dragInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#region Синхронная реализация
|
||||
|
||||
public bool CanStartDrag(out DragInfo? dragInfo)
|
||||
{
|
||||
return _syncSource.CanStartDrag(out dragInfo);
|
||||
}
|
||||
|
||||
public bool StartDrag(DragInfo dragInfo)
|
||||
{
|
||||
return _syncSource.StartDrag(dragInfo);
|
||||
}
|
||||
|
||||
public void DragCompleted(DragInfo dragInfo, DragDropEffects effects)
|
||||
{
|
||||
_syncSource.DragCompleted(dragInfo, effects);
|
||||
}
|
||||
|
||||
public void DragCancelled(DragInfo dragInfo)
|
||||
{
|
||||
_syncSource.DragCancelled(dragInfo);
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Комбинированная цель, поддерживающая как синхронный, так и асинхронный API.
|
||||
/// </summary>
|
||||
private sealed class CombinedDropTarget : IAsyncDropTarget
|
||||
{
|
||||
private readonly IDropTarget _syncTarget;
|
||||
private readonly IAsyncDropTarget _asyncTarget;
|
||||
private readonly bool _preferAsync;
|
||||
|
||||
public CombinedDropTarget(IDropTarget syncTarget, IAsyncDropTarget asyncTarget, bool preferAsync)
|
||||
{
|
||||
_syncTarget = syncTarget ?? throw new ArgumentNullException(nameof(syncTarget));
|
||||
_asyncTarget = asyncTarget ?? throw new ArgumentNullException(nameof(asyncTarget));
|
||||
_preferAsync = preferAsync;
|
||||
}
|
||||
|
||||
public async Task<bool> CanAcceptDropAsync(DropInfo dropInfo)
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
return await _asyncTarget.CanAcceptDropAsync(dropInfo).ConfigureAwait(false);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
return await Task.Run(() => _syncTarget.CanAcceptDrop(dropInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragOverAsync(DropInfo dropInfo)
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _asyncTarget.DragOverAsync(dropInfo).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Run(() => _syncTarget.DragOver(dropInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DropAsync(DropInfo dropInfo)
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _asyncTarget.DropAsync(dropInfo).ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Run(() => _syncTarget.Drop(dropInfo)).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
public async Task DragLeaveAsync()
|
||||
{
|
||||
if (_preferAsync)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _asyncTarget.DragLeaveAsync().ConfigureAwait(false);
|
||||
return;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// В случае ошибки пробуем синхронную версию
|
||||
}
|
||||
}
|
||||
|
||||
await Task.Run(() => _syncTarget.DragLeave()).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
#region Синхронная реализация
|
||||
|
||||
public bool CanAcceptDrop(DropInfo dropInfo)
|
||||
{
|
||||
return _syncTarget.CanAcceptDrop(dropInfo);
|
||||
}
|
||||
|
||||
public void DragOver(DropInfo dropInfo)
|
||||
{
|
||||
_syncTarget.DragOver(dropInfo);
|
||||
}
|
||||
|
||||
public void Drop(DropInfo dropInfo)
|
||||
{
|
||||
_syncTarget.Drop(dropInfo);
|
||||
}
|
||||
|
||||
public void DragLeave()
|
||||
{
|
||||
_syncTarget.DragLeave();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
Reference in New Issue
Block a user