[英]How to prevent listbox items being dragged if mouse down is on certain controls
I would like some advice on drag and drop operations of listbox items. 我想要一些有关列表框项目的拖放操作的建议。 Each of my items has a ComboBox, TextBox, CheckBox and Button, as shown below.
我的每个项目都有一个ComboBox,TextBox,CheckBox和Button,如下所示。
I use my drag/drop to reorder these and it is almost working correctly. 我使用拖放操作重新排序,它们几乎可以正常工作。
The main issue is that a drag operation on an item is occurring when a PreviewMouseLeftButtonDown and PreviewMouseMove event happens on one of the controls noted above. 主要问题是,当在上面提到的控件之一上发生PreviewMouseLeftButtonDown和PreviewMouseMove事件时,正在对项目进行拖动操作。
My question is given the code below what's good way I can prevent this drag occuring when one of the controls is clicked on? 下面的代码给出了我的问题,当单击其中一个控件时,有什么好的方法可以防止这种拖动发生?
XAML: 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#: 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;
}
}
}
I tend to initialise my Drag and Drop properties in a PreviewMouseDown
event handler, but it's unwise to perform any other Drag and Drop operations in that handler, because the user might not be dragging... they might just have clicked. 我倾向于在
PreviewMouseDown
事件处理程序中初始化我的拖放属性,但是在该处理程序中执行任何其他拖放操作是不明智的,因为用户可能不会拖动...他们可能只是单击了。
Instead, it's better to handle the PreviewMouseMove
event to initiate a Drag and Drop operation. 相反,最好处理
PreviewMouseMove
事件以启动拖放操作。 Here is a simplified example: 这是一个简化的示例:
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);
}
}
It is in the PreviewMouseMove
event handler that you could check which UI element has been clicked on and determine whether you start the Drag and Drop operation or not. 您可以在
PreviewMouseMove
事件处理程序中检查单击了哪个UI元素,并确定是否启动拖放操作。 Try something like this: 尝试这样的事情:
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);
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.