У меня есть UserControls, которые у меня есть в ListBox, который затем размещает их на холсте.Затем я сделал перетаскивание UserControls на холсте с помощью DraggableExtender ( Перетаскивание изображения в WPF ).
Но с тех пор, как я перешел с ItemsControl на ListBox, чтобы можно было сделатьвыбираемые элементы управления, перетаскивание работает очень плохо.Например, если я перетаскиваю элемент управления на другой элемент управления, другой элемент управления становится сфокусированным и придерживается перетаскивания.Также, если я перемещаю мышь за пределы холста, пользовательский контроль застревает на краю, и я теряю перетаскивающий фокус, как будто CaptureMouse не работает.
ListBox выглядит следующим образом (когда он работал до того, как был ItemsControl):
<ListBox ItemsSource="{Binding Components}" SelectedItem="{Binding SelectedItem}" Background="Transparent">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<Canvas ClipToBounds="True" Height="{Binding CurrentProject.Height, Converter={StaticResource SizeConverter}}"
Width="{Binding CurrentProject.Width, Converter={StaticResource SizeConverter}}"
HorizontalAlignment="Left" VerticalAlignment="Top">
<Canvas.Background>
<SolidColorBrush Color="{DynamicResource {x:Static SystemColors.WindowFrameColorKey}}"/>
</Canvas.Background>
</Canvas>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<ListBox.ItemContainerStyle>
<Style TargetType="{x:Type ListBoxItem}">
<Setter Property="HorizontalAlignment" Value="Stretch" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Grid>
<Border Background="{TemplateBinding Background}" />
<ContentPresenter/>
</Grid>
<ControlTemplate.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsMouseOver" Value="True" />
<Condition Property="IsSelected" Value="False"/>
</MultiTrigger.Conditions>
<Setter Property="Background" Value="#8868D5FD" />
</MultiTrigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="#4468D5FD" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Utils:DraggableExtender.CanDrag" Value="True" />
<Setter Property="Canvas.Top" Value="{Binding Path=Conveyor.Y, Converter={StaticResource SizeConverter},Mode=TwoWay}" />
<Setter Property="Canvas.Left" Value="{Binding Path=Conveyor.X, Converter={StaticResource SizeConverter},Mode=TwoWay}" />
</Style>
</ListBox.ItemContainerStyle>
</ListBox>
Мой DraggableExtender выглядит следующим образом:
public class DraggableExtender : DependencyObject
{
public static readonly DependencyProperty CanDragProperty =
DependencyProperty.RegisterAttached("CanDrag", typeof(bool), typeof(DraggableExtender),
new UIPropertyMetadata(false, OnChangeCanDragProperty));
private static bool isDragging = false;
private static Point offset;
public static void SetCanDrag(UIElement element, bool o)
{
element.SetValue(CanDragProperty, o);
}
public static bool GetCanDrag(UIElement element, bool o)
{
return (bool)element.GetValue(CanDragProperty);
}
private static void OnChangeCanDragProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
UIElement element = d as UIElement;
if (element == null) return;
if (e.NewValue != e.OldValue)
{
if ((bool)e.NewValue)
{
element.PreviewMouseDown += element_PreviewMouseDown;
element.PreviewMouseUp += element_PreviewMouseUp;
element.PreviewMouseMove += element_PreviewMouseMove;
}
else
{
element.PreviewMouseDown -= element_PreviewMouseDown;
element.PreviewMouseUp -= element_PreviewMouseUp;
element.PreviewMouseMove -= element_PreviewMouseMove;
}
}
}
private static void element_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element == null) return;
Debug.WriteLine(element);
isDragging = true;
element.CaptureMouse();
offset = e.GetPosition(element);
}
private static void element_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (!isDragging) return;
FrameworkElement element = sender as FrameworkElement;
if (element == null) return;
Canvas canvas = element.FindAncestor<Canvas>();
if (canvas == null) return;
Point mousePoint = e.GetPosition(canvas);
mousePoint.Offset(-offset.X, -offset.Y);
element.SetValue(Canvas.LeftProperty, mousePoint.X);
element.SetValue(Canvas.TopProperty, mousePoint.Y);
}
private static void element_PreviewMouseUp(object sender, MouseButtonEventArgs e)
{
FrameworkElement element = sender as FrameworkElement;
if (element == null) return;
element.ReleaseMouseCapture();
isDragging = false;
}
}
Я пытался найти решение, но до сих пор мне не удалось.У кого-нибудь есть идеи, почему это происходит и как я могу это решить?