Убраны синхронные методы
This commit is contained in:
@@ -1,58 +1,31 @@
|
||||
using Lattice.Core.Geometry;
|
||||
using Lattice.Core.DragDrop.Models;
|
||||
using Lattice.Core.Geometry;
|
||||
using Lattice.UI.DragDrop.Behaviors;
|
||||
using Microsoft.UI.Xaml;
|
||||
using Microsoft.UI.Xaml.Controls;
|
||||
using Microsoft.UI.Xaml.Input;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Lattice.UI.DragDrop.WinUI.Behaviors;
|
||||
|
||||
/// <summary>
|
||||
/// Поведение источника перетаскивания для WinUI UIElement.
|
||||
/// Исправленная версия с правильной очисткой ресурсов.
|
||||
/// Поведение источника перетаскивания для WinUI FrameworkElement.
|
||||
/// </summary>
|
||||
public static class WinUIDragSourceBehavior
|
||||
public class WinUIDragSourceBehavior : DragSourceBehaviorBase<FrameworkElement>
|
||||
{
|
||||
#region Вложенные типы
|
||||
|
||||
private sealed class DragSourceContext : IDisposable
|
||||
{
|
||||
public Point DragStartPosition { get; set; }
|
||||
public bool IsDragging { get; set; }
|
||||
public UIElement? CurrentDragElement { get; set; }
|
||||
public object? DragData { get; set; }
|
||||
public Action<UIElement>? DragStartedHandler { get; set; }
|
||||
public Action<UIElement, Core.DragDrop.Enums.DragDropEffects>? DragCompletedHandler { get; set; }
|
||||
public Core.DragDrop.Enums.DragDropEffects AllowedEffects { get; set; }
|
||||
= Core.DragDrop.Enums.DragDropEffects.Copy | Core.DragDrop.Enums.DragDropEffects.Move;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
DragStartedHandler = null;
|
||||
DragCompletedHandler = null;
|
||||
DragData = null;
|
||||
CurrentDragElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Прикрепленные свойства
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор свойства для привязки данных перетаскивания.
|
||||
/// Прикрепленное свойство для данных перетаскивания.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DragDataProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"DragData",
|
||||
typeof(object),
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
new PropertyMetadata(null, OnDragDataChanged));
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор свойства для включения перетаскивания.
|
||||
/// Прикрепленное свойство для включения перетаскивания.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty IsEnabledProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
@@ -62,368 +35,256 @@ public static class WinUIDragSourceBehavior
|
||||
new PropertyMetadata(false, OnIsEnabledChanged));
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор свойства для разрешенных эффектов перетаскивания.
|
||||
/// Получает значение DragData.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty AllowedEffectsProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"AllowedEffects",
|
||||
typeof(Core.DragDrop.Enums.DragDropEffects),
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
new PropertyMetadata(Core.DragDrop.Enums.DragDropEffects.Copy | Core.DragDrop.Enums.DragDropEffects.Move));
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор свойства для обработчика начала перетаскивания.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DragStartedHandlerProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"DragStartedHandler",
|
||||
typeof(Action<UIElement>),
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор свойства для обработчика завершения перетаскивания.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DragCompletedHandlerProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"DragCompletedHandler",
|
||||
typeof(Action<UIElement, Core.DragDrop.Enums.DragDropEffects>),
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
/// <summary>
|
||||
/// Идентификатор свойства для обработчика создания данных перетаскивания.
|
||||
/// </summary>
|
||||
public static readonly DependencyProperty DragDataFactoryProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"DragDataFactory",
|
||||
typeof(Func<UIElement, Task<object>>),
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
#endregion
|
||||
|
||||
#region Статические поля
|
||||
|
||||
private static readonly ConditionalWeakTable<UIElement, DragSourceContext> _contexts = new();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Методы доступа к свойствам
|
||||
|
||||
/// <summary>
|
||||
/// Получает значение свойства DragData для указанного элемента.
|
||||
/// </summary>
|
||||
public static object GetDragData(UIElement element) =>
|
||||
element.GetValue(DragDataProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает значение свойства DragData для указанного элемента.
|
||||
/// </summary>
|
||||
public static void SetDragData(UIElement element, object value) =>
|
||||
element.SetValue(DragDataProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// Получает значение свойства IsEnabled для указанного элемента.
|
||||
/// </summary>
|
||||
public static bool GetIsEnabled(UIElement element) =>
|
||||
(bool)element.GetValue(IsEnabledProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает значение свойства IsEnabled для указанного элемента.
|
||||
/// </summary>
|
||||
public static void SetIsEnabled(UIElement element, bool value) =>
|
||||
element.SetValue(IsEnabledProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// Получает значение свойства AllowedEffects для указанного элемента.
|
||||
/// </summary>
|
||||
public static Core.DragDrop.Enums.DragDropEffects GetAllowedEffects(UIElement element) =>
|
||||
(Core.DragDrop.Enums.DragDropEffects)element.GetValue(AllowedEffectsProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает значение свойства AllowedEffects для указанного элемента.
|
||||
/// </summary>
|
||||
public static void SetAllowedEffects(UIElement element, Core.DragDrop.Enums.DragDropEffects value) =>
|
||||
element.SetValue(AllowedEffectsProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// Получает обработчик начала перетаскивания.
|
||||
/// </summary>
|
||||
public static Action<UIElement> GetDragStartedHandler(UIElement element) =>
|
||||
(Action<UIElement>)element.GetValue(DragStartedHandlerProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает обработчик начала перетаскивания.
|
||||
/// </summary>
|
||||
public static void SetDragStartedHandler(UIElement element, Action<UIElement> value) =>
|
||||
element.SetValue(DragStartedHandlerProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// Получает обработчик завершения перетаскивания.
|
||||
/// </summary>
|
||||
public static Action<UIElement, Core.DragDrop.Enums.DragDropEffects> GetDragCompletedHandler(UIElement element) =>
|
||||
(Action<UIElement, Core.DragDrop.Enums.DragDropEffects>)element.GetValue(DragCompletedHandlerProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает обработчик завершения перетаскивания.
|
||||
/// </summary>
|
||||
public static void SetDragCompletedHandler(UIElement element, Action<UIElement, Core.DragDrop.Enums.DragDropEffects> value) =>
|
||||
element.SetValue(DragCompletedHandlerProperty, value);
|
||||
|
||||
/// <summary>
|
||||
/// Получает фабрику данных перетаскивания.
|
||||
/// </summary>
|
||||
public static Func<UIElement, Task<object>> GetDragDataFactory(UIElement element) =>
|
||||
(Func<UIElement, Task<object>>)element.GetValue(DragDataFactoryProperty);
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает фабрику данных перетаскивания.
|
||||
/// </summary>
|
||||
public static void SetDragDataFactory(UIElement element, Func<UIElement, Task<object>> value) =>
|
||||
element.SetValue(DragDataFactoryProperty, value);
|
||||
|
||||
#endregion
|
||||
|
||||
#region Обработчики изменений свойств
|
||||
|
||||
private static void OnDragDataChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
public static object GetDragData(FrameworkElement element)
|
||||
{
|
||||
if (d is UIElement element)
|
||||
{
|
||||
if (_contexts.TryGetValue(element, out var context))
|
||||
{
|
||||
context.DragData = e.NewValue;
|
||||
}
|
||||
}
|
||||
return element.GetValue(DragDataProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает значение DragData.
|
||||
/// </summary>
|
||||
public static void SetDragData(FrameworkElement element, object value)
|
||||
{
|
||||
element.SetValue(DragDataProperty, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Получает значение IsEnabled.
|
||||
/// </summary>
|
||||
public static bool GetIsEnabled(FrameworkElement element)
|
||||
{
|
||||
return (bool)element.GetValue(IsEnabledProperty);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Устанавливает значение IsEnabled.
|
||||
/// </summary>
|
||||
public static void SetIsEnabled(FrameworkElement element, bool value)
|
||||
{
|
||||
element.SetValue(IsEnabledProperty, value);
|
||||
}
|
||||
|
||||
private static void OnIsEnabledChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
if (d is UIElement element)
|
||||
if (d is FrameworkElement element)
|
||||
{
|
||||
// Получаем или создаем экземпляр поведения через Attached Property
|
||||
var behavior = GetBehavior(element);
|
||||
|
||||
if ((bool)e.NewValue)
|
||||
{
|
||||
EnableDrag(element);
|
||||
if (behavior == null)
|
||||
{
|
||||
behavior = new WinUIDragSourceBehavior();
|
||||
SetBehavior(element, behavior);
|
||||
}
|
||||
|
||||
behavior.AssociatedElement = element;
|
||||
}
|
||||
else
|
||||
{
|
||||
DisableDrag(element);
|
||||
if (behavior != null)
|
||||
{
|
||||
behavior.Detach();
|
||||
SetBehavior(element, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Включение/выключение перетаскивания
|
||||
|
||||
private static void EnableDrag(UIElement element)
|
||||
public WinUIDragSourceBehavior()
|
||||
: base(ServiceProviderHelper.GetServiceProvider())
|
||||
{
|
||||
if (_contexts.TryGetValue(element, out _))
|
||||
return;
|
||||
|
||||
var context = new DragSourceContext
|
||||
{
|
||||
DragData = GetDragData(element),
|
||||
DragStartedHandler = GetDragStartedHandler(element),
|
||||
DragCompletedHandler = GetDragCompletedHandler(element),
|
||||
AllowedEffects = GetAllowedEffects(element)
|
||||
};
|
||||
|
||||
_contexts.Add(element, context);
|
||||
}
|
||||
|
||||
protected override void SubscribeToEvents(FrameworkElement element)
|
||||
{
|
||||
element.PointerPressed += OnPointerPressed;
|
||||
element.PointerMoved += OnPointerMoved;
|
||||
element.PointerReleased += OnPointerReleased;
|
||||
element.PointerCanceled += OnPointerCanceled;
|
||||
element.PointerCaptureLost += OnPointerCaptureLost;
|
||||
element.Unloaded += OnElementUnloaded;
|
||||
element.LostFocus += OnLostFocus;
|
||||
}
|
||||
|
||||
private static void DisableDrag(UIElement element)
|
||||
protected override void UnsubscribeFromEvents(FrameworkElement element)
|
||||
{
|
||||
element.PointerPressed -= OnPointerPressed;
|
||||
element.PointerMoved -= OnPointerMoved;
|
||||
element.PointerReleased -= OnPointerReleased;
|
||||
element.PointerCanceled -= OnPointerCanceled;
|
||||
element.PointerCaptureLost -= OnPointerCaptureLost;
|
||||
element.Unloaded -= OnElementUnloaded;
|
||||
element.LostFocus -= OnLostFocus;
|
||||
}
|
||||
|
||||
if (_contexts.TryGetValue(element, out var context))
|
||||
private void OnPointerPressed(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
if (AssociatedElement == null) return;
|
||||
|
||||
var point = e.GetCurrentPoint(AssociatedElement);
|
||||
OnInteractionStarted(new Point(point.Position.X, point.Position.Y));
|
||||
}
|
||||
|
||||
private void OnPointerMoved(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
if (AssociatedElement == null) return;
|
||||
|
||||
var point = e.GetCurrentPoint(AssociatedElement);
|
||||
OnInteractionMoved(new Point(point.Position.X, point.Position.Y));
|
||||
}
|
||||
|
||||
private void OnPointerReleased(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
OnInteractionEnded();
|
||||
}
|
||||
|
||||
private void OnPointerCanceled(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
OnInteractionCancelled();
|
||||
}
|
||||
|
||||
private void OnPointerCaptureLost(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
OnInteractionCancelled();
|
||||
}
|
||||
|
||||
private void OnLostFocus(object sender, RoutedEventArgs e)
|
||||
{
|
||||
OnInteractionCancelled();
|
||||
}
|
||||
|
||||
protected override Point ConvertToScreenCoordinates(Point point)
|
||||
{
|
||||
if (AssociatedElement == null)
|
||||
return point;
|
||||
|
||||
var transform = AssociatedElement.TransformToVisual(null);
|
||||
var screenPoint = transform.TransformPoint(new Windows.Foundation.Point(point.X, point.Y));
|
||||
return new Point(screenPoint.X, screenPoint.Y);
|
||||
}
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override async Task<(bool CanStart, DragInfo? DragInfo)> CanStartDragAsync()
|
||||
{
|
||||
if (AssociatedElement == null)
|
||||
{
|
||||
context.Dispose();
|
||||
_contexts.Remove(element);
|
||||
return (false, null);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Обработчики событий
|
||||
|
||||
private static void OnPointerPressed(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
if (sender is UIElement element && _contexts.TryGetValue(element, out var context))
|
||||
var data = GetDragData(AssociatedElement);
|
||||
if (data == null)
|
||||
{
|
||||
var point = e.GetCurrentPoint(element);
|
||||
context.DragStartPosition = new Point(point.Position.X, point.Position.Y);
|
||||
context.CurrentDragElement = element;
|
||||
element.CapturePointer(e.Pointer);
|
||||
// Пробуем получить данные из Tag или других источников
|
||||
data = AssociatedElement.Tag ?? AssociatedElement.DataContext;
|
||||
}
|
||||
}
|
||||
|
||||
private static async void OnPointerMoved(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
if (sender is UIElement element && _contexts.TryGetValue(element, out var context))
|
||||
if (data == null)
|
||||
{
|
||||
if (context.IsDragging || context.CurrentDragElement == null)
|
||||
return;
|
||||
|
||||
var currentPoint = e.GetCurrentPoint(context.CurrentDragElement);
|
||||
var currentPosition = new Point(currentPoint.Position.X, currentPoint.Position.Y);
|
||||
|
||||
var distance = CalculateDistance(context.DragStartPosition, currentPosition);
|
||||
if (distance > 3.0) // Порог перетаскивания
|
||||
{
|
||||
context.IsDragging = true;
|
||||
await StartDragAsync(context.CurrentDragElement, currentPosition, context);
|
||||
}
|
||||
return (false, null);
|
||||
}
|
||||
|
||||
// Получаем начальную позицию в экранных координатах
|
||||
var startPosition = ConvertToScreenCoordinates(_dragStartPosition);
|
||||
|
||||
// Создаем DragInfo с учетом вашего конструктора
|
||||
var dragInfo = new DragInfo(
|
||||
data: data,
|
||||
allowedEffects: Core.DragDrop.Enums.DragDropEffects.Move |
|
||||
Core.DragDrop.Enums.DragDropEffects.Copy,
|
||||
startPosition: startPosition,
|
||||
source: this
|
||||
);
|
||||
|
||||
return (true, dragInfo);
|
||||
}
|
||||
|
||||
private static async Task StartDragAsync(UIElement element, Point currentPosition, DragSourceContext context)
|
||||
protected override void OnDragCompleted(DragInfo dragInfo, Core.DragDrop.Enums.DragDropEffects effects)
|
||||
{
|
||||
try
|
||||
{
|
||||
object? data = context.DragData;
|
||||
base.OnDragCompleted(dragInfo, effects);
|
||||
|
||||
// Если есть фабрика данных, используем ее
|
||||
var factory = GetDragDataFactory(element);
|
||||
if (factory != null)
|
||||
{
|
||||
data = await factory(element);
|
||||
}
|
||||
|
||||
if (data != null)
|
||||
{
|
||||
context.DragData = data;
|
||||
|
||||
// Вызываем обработчик начала перетаскивания
|
||||
context.DragStartedHandler?.Invoke(element);
|
||||
|
||||
// Устанавливаем визуальный эффект
|
||||
SetDragVisualState(element, true);
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
System.Diagnostics.Debug.WriteLine($"Error starting drag: {ex.Message}");
|
||||
context.IsDragging = false;
|
||||
}
|
||||
// Визуальная обратная связь при завершении
|
||||
SetVisualState(AssociatedElement, "Normal");
|
||||
}
|
||||
|
||||
private static void OnPointerReleased(object sender, PointerRoutedEventArgs e)
|
||||
protected override void OnDragCancelled(DragInfo dragInfo)
|
||||
{
|
||||
CompleteDrag(sender as UIElement, Core.DragDrop.Enums.DragDropEffects.Copy);
|
||||
base.OnDragCancelled(dragInfo);
|
||||
|
||||
// Визуальная обратная связь при отмене
|
||||
SetVisualState(AssociatedElement, "Normal");
|
||||
}
|
||||
|
||||
private static void OnPointerCanceled(object sender, PointerRoutedEventArgs e)
|
||||
private void SetVisualState(FrameworkElement? element, string stateName)
|
||||
{
|
||||
CompleteDrag(sender as UIElement, Core.DragDrop.Enums.DragDropEffects.None);
|
||||
}
|
||||
|
||||
private static void OnPointerCaptureLost(object sender, PointerRoutedEventArgs e)
|
||||
{
|
||||
CompleteDrag(sender as UIElement, Core.DragDrop.Enums.DragDropEffects.None);
|
||||
}
|
||||
|
||||
private static void OnElementUnloaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (sender is UIElement element)
|
||||
{
|
||||
DisableDrag(element);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Вспомогательные методы
|
||||
|
||||
private static void CompleteDrag(UIElement? element, Core.DragDrop.Enums.DragDropEffects effects)
|
||||
{
|
||||
if (element != null && _contexts.TryGetValue(element, out var context))
|
||||
{
|
||||
// Вызываем обработчик завершения перетаскивания
|
||||
context.DragCompletedHandler?.Invoke(element, effects);
|
||||
|
||||
// Сбрасываем визуальный эффект
|
||||
SetDragVisualState(element, false);
|
||||
|
||||
element.ReleasePointerCaptures();
|
||||
|
||||
ResetDragState(context);
|
||||
}
|
||||
}
|
||||
|
||||
private static void SetDragVisualState(UIElement element, bool isDragging)
|
||||
{
|
||||
// Для элементов, которые являются Control, используем VisualStateManager
|
||||
if (element is Control control)
|
||||
{
|
||||
// Пытаемся перейти к состоянию "Dragging" или "Normal"
|
||||
try
|
||||
{
|
||||
VisualStateManager.GoToState(control, isDragging ? "Dragging" : "Normal", true);
|
||||
VisualStateManager.GoToState(control, stateName, true);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Если состояния не определены, меняем свойства напрямую
|
||||
control.Opacity = isDragging ? 0.7 : 1.0;
|
||||
// Fallback
|
||||
control.Opacity = 1.0;
|
||||
}
|
||||
}
|
||||
else
|
||||
else if (element != null)
|
||||
{
|
||||
// Для обычных UIElement меняем свойства напрямую
|
||||
element.Opacity = isDragging ? 0.7 : 1.0;
|
||||
// Альтернативная визуальная обратная связь для не-Control элементов
|
||||
element.Opacity = 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
private static double CalculateDistance(Point p1, Point p2)
|
||||
// Attached property для хранения экземпляра поведения
|
||||
private static readonly DependencyProperty BehaviorProperty =
|
||||
DependencyProperty.RegisterAttached(
|
||||
"Behavior",
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
typeof(WinUIDragSourceBehavior),
|
||||
new PropertyMetadata(null));
|
||||
|
||||
private static WinUIDragSourceBehavior GetBehavior(FrameworkElement element)
|
||||
{
|
||||
var dx = p2.X - p1.X;
|
||||
var dy = p2.Y - p1.Y;
|
||||
return Math.Sqrt(dx * dx + dy * dy);
|
||||
return (WinUIDragSourceBehavior)element.GetValue(BehaviorProperty);
|
||||
}
|
||||
|
||||
private static void ResetDragState(DragSourceContext context)
|
||||
private static void SetBehavior(FrameworkElement element, WinUIDragSourceBehavior? value)
|
||||
{
|
||||
context.IsDragging = false;
|
||||
context.CurrentDragElement = null;
|
||||
context.DragStartPosition = default;
|
||||
element.SetValue(BehaviorProperty, value);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
/// <summary>
|
||||
/// Вспомогательный класс для получения IServiceProvider.
|
||||
/// </summary>
|
||||
internal static class ServiceProviderHelper
|
||||
{
|
||||
private static IServiceProvider? _serviceProvider;
|
||||
|
||||
#region Методы очистки
|
||||
|
||||
/// <summary>
|
||||
/// Очищает все ресурсы, связанные с поведением перетаскивания.
|
||||
/// </summary>
|
||||
public static void Cleanup()
|
||||
public static IServiceProvider GetServiceProvider()
|
||||
{
|
||||
var elements = new List<UIElement>();
|
||||
|
||||
foreach (var kvp in _contexts)
|
||||
if (_serviceProvider == null)
|
||||
{
|
||||
elements.Add(kvp.Key);
|
||||
// Ищем IServiceProvider в Application.Current.Resources
|
||||
if (Application.Current.Resources.TryGetValue("ServiceProvider", out var provider) &&
|
||||
provider is IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
"IServiceProvider не найден. Убедитесь, что ServiceProvider зарегистрирован в ресурсах приложения.");
|
||||
}
|
||||
}
|
||||
|
||||
foreach (var element in elements)
|
||||
{
|
||||
DisableDrag(element);
|
||||
}
|
||||
|
||||
_contexts.Clear();
|
||||
return _serviceProvider;
|
||||
}
|
||||
|
||||
#endregion
|
||||
public static void SetServiceProvider(IServiceProvider serviceProvider)
|
||||
{
|
||||
_serviceProvider = serviceProvider;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user