リストボックスアイテムのドラッグアンドドロップ操作についてアドバイスをお願いします。以下に示すように、各アイテムにはComboBox、TextBox、CheckBox、およびButtonがあります。
ドラッグアンドドロップを使用してこれらを並べ替えましたが、ほぼ正しく機能しています。
主な問題は、上記のコントロールの1つでPreviewMouseLeftButtonDownイベントとPreviewMouseMoveイベントが発生したときに、アイテムのドラッグ操作が発生していることです。
私の質問は、コントロールの1つがクリックされたときにこのドラッグが発生するのを防ぐための良い方法は何ですか?
XAML:
<DataTemplate DataType="{x:Type helpers:Filter}">
<Border>
<Border>
<Grid>
<ComboBox />
<TextBox />
<CheckBox />
<Button />
</Grid>
</Border>
</Border>
</DataTemplate>
<ListBox x:Name="FilterList"
ItemsSource="{Binding Filters}"
helpers:DragDropHelper.IsDragSource="true"
helpers:DragDropHelper.IsDropTarget="true" />
C#:
public static readonly DependencyProperty IsDragSourceProperty =
DependencyProperty.RegisterAttached("IsDragSource", typeof(bool), typeof(DragDropHelper), new UIPropertyMetadata(false, IsDragSourceChanged));
private void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
this.sourceItemsControl = (ItemsControl)sender;
Visual visual = e.OriginalSource as Visual;
this.topWindow = Window.GetWindow(this.sourceItemsControl);
this.initialMousePosition = e.GetPosition(this.topWindow);
this.sourceItemContainer = sourceItemsControl.ContainerFromElement(visual) as FrameworkElement;
if (this.sourceItemContainer != null)
{
this.draggedData = this.sourceItemContainer.DataContext;
}
}
// Drag = mouse down + move by a certain amount
private void DragSource_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (this.draggedData != null)
{
// Only drag when user moved the mouse by a reasonable amount.
if (Utilities.IsMovementBigEnough(this.initialMousePosition, e.GetPosition(this.topWindow)))
{
this.initialMouseOffset = this.initialMousePosition - this.sourceItemContainer.TranslatePoint(new Point(0, 0), this.topWindow);
DataObject data = new DataObject(this.format.Name, this.draggedData);
// Adding events to the window to make sure dragged adorner comes up when mouse is not over a drop target.
bool previousAllowDrop = this.topWindow.AllowDrop;
this.topWindow.AllowDrop = true;
this.topWindow.DragEnter += TopWindow_DragEnter;
this.topWindow.DragOver += TopWindow_DragOver;
this.topWindow.DragLeave += TopWindow_DragLeave;
DragDropEffects effects = DragDrop.DoDragDrop((DependencyObject)sender, data, DragDropEffects.Move);
RemoveDraggedAdorner();
this.topWindow.AllowDrop = previousAllowDrop;
this.topWindow.DragEnter -= TopWindow_DragEnter;
this.topWindow.DragOver -= TopWindow_DragOver;
this.topWindow.DragLeave -= TopWindow_DragLeave;
this.draggedData = null;
}
}
}
私はPreviewMouseDown
イベントハンドラーでドラッグアンドドロッププロパティを初期化する傾向がありますが、ユーザーがドラッグしていない可能性があるため、そのハンドラーで他のドラッグアンドドロップ操作を実行することは賢明ではありません...クリックしただけかもしれません。
代わりに、PreviewMouseMove
イベントを処理してドラッグアンドドロップ操作を開始することをお勧めします。簡単な例を次に示します。
private void DragSourcePreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
isMouseDown = true;
}
private void DragSourcePreviewMouseMove(object sender, MouseEventArgs e)
{
if (isMouseDown && IsConfirmedDrag(e.GetPosition(sender as ListBox)))
{
isMouseDown = false;
...
DragDrop.DoDragDrop(dragSource, data, DragDropEffects);
}
}
PreviewMouseMove
どのUI要素がクリックされたかを確認し、ドラッグアンドドロップ操作を開始するかどうかを決定できるのは、イベントハンドラーです。次のようなものを試してください。
private void DragSourcePreviewMouseMove(object sender, MouseEventArgs e)
{
ListBox dragSourceControl = (ListBox)sender;
HitTestResult result = VisualTreeHelper.HitTest(dragSourceControl,
Mouse.GetPosition(dragSourceControl));
UIElement draggedUIElement = result.VisualHit.GetParentOfType<ListBoxItem>();
bool isViable = AddYourViabilityConditionHere(draggedUIElement);
if (isMouseDown && IsConfirmedDrag(e.GetPosition(sender as ListBox)) && isViable)
{
isMouseDown = false;
...
DragDrop.DoDragDrop(dragSource, data, DragDropEffects);
}
}
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加