当 PreviewMouseLeftButtonDownCommand RelayCommand\EventToCommand 触发时查找 ItemsControl 中的选定项目

发布于 2024-11-28 14:48:17 字数 1843 浏览 0 评论 0原文

我的应用程序是 wpf mvvm,使用 RelayCommand\EventToCommand 绑定事件。我的应用程序执行一些典型的拖放操作从 ListBox 拖放到 ItemsControl 上(它实际上是一个图像控件,顶部有一个 ItemsControl,用于保存拖放的项目)。 ListBox 中填充有 vm ObservableCollection。 ItemsControl 也是一个 ObservableCollection,我将放置的 MyObj 项目插入其中。

当我从 ListBox 中拖动项目并将其放入 ItemsControl\image 时,一切正常。在 PreviewMouseLeftButtonDownCommand 中,我使用 System.Windows.Media.VisualTreeHelper 递归地向上遍历可视化树,因此当我从 ListBox 中拖动时,我可以找到正在拖动的 MyObj 项。但是,当我尝试从 ItemsControl 中拖动项目时,代码不起作用。我所能得到的只是项目(标签)的 DataTemplate 转换。所以我的问题是;当 PreviewMouseLeftButtonDownCommand RelayCommand\EventToCommand 触发时,如何从 ItemsControl 获取所选项目?

虚拟机 C#:

PreviewMouseLeftButtonDownCommand = new RelayCommand<MouseButtonEventArgs>(e =>
{
    if (e.Source is ListBox)
    {
    // get dragged list box item
    ListBox listBox = e.Source as ListBox;
    ListBoxItem listBoxItem = VisualHelper.FindAncestor<ListBoxItem>((DependencyObject)e.OriginalSource);

    // Find the data behind the listBoxItem
    if (listBox == null || listBoxItem == null) return;

    MyObj tag = (MyObj)listBox.ItemContainerGenerator.ItemFromContainer(listBoxItem);

     // Initialize the drag & drop operation
    DataObject dragData = new DataObject("myObj", tag);
    DragDrop.DoDragDrop(listBoxItem, dragData, DragDropEffects.Move);
}
else if (e.Source is ItemsControl)
{
    ItemsControl itemsControl = e.Source as ItemsControl;
    object item = VisualHelper.FindAncestor<UIElement>((DependencyObject)e.OriginalSource);

    if (itemsControl == null || item == null) return;

    MyObj tag = (MyObj)itemsControl.ItemContainerGenerator.ItemFromContainer(item);


    // Initialize the drag & drop operation
    DataObject dragData = new DataObject("myObj", tagDragging);
    DragDrop.DoDragDrop(item, dragData, DragDropEffects.Move);
    }
});

My app is wpf mvvm, using RelayCommand\EventToCommand bindings for the events. My app does some typical drag & drop from a ListBox onto an ItemsControl (it is actually an image control with an ItemsControl on top, that is holding the dropped items). The ListBox is populated with a vm ObservableCollection. And the ItemsControl is also an ObservableCollection that I insert the dropped MyObj items into.

When I drag items from the ListBox and drop them in to\on to the ItemsControl\image it all works fine. In the PreviewMouseLeftButtonDownCommand I use the System.Windows.Media.VisualTreeHelper to recursively walk up the visual tree, so when I drag from the ListBox I can find the MyObj item that is being dragged. But when I try drag an item from the ItemsControl the code does not work. All I can get back is the DataTemplate conversion of the item (a lable). So my question is; how do I get the selected item from my ItemsControl when the PreviewMouseLeftButtonDownCommand RelayCommand\EventToCommand fires?

the vm C#:

PreviewMouseLeftButtonDownCommand = new RelayCommand<MouseButtonEventArgs>(e =>
{
    if (e.Source is ListBox)
    {
    // get dragged list box item
    ListBox listBox = e.Source as ListBox;
    ListBoxItem listBoxItem = VisualHelper.FindAncestor<ListBoxItem>((DependencyObject)e.OriginalSource);

    // Find the data behind the listBoxItem
    if (listBox == null || listBoxItem == null) return;

    MyObj tag = (MyObj)listBox.ItemContainerGenerator.ItemFromContainer(listBoxItem);

     // Initialize the drag & drop operation
    DataObject dragData = new DataObject("myObj", tag);
    DragDrop.DoDragDrop(listBoxItem, dragData, DragDropEffects.Move);
}
else if (e.Source is ItemsControl)
{
    ItemsControl itemsControl = e.Source as ItemsControl;
    object item = VisualHelper.FindAncestor<UIElement>((DependencyObject)e.OriginalSource);

    if (itemsControl == null || item == null) return;

    MyObj tag = (MyObj)itemsControl.ItemContainerGenerator.ItemFromContainer(item);


    // Initialize the drag & drop operation
    DataObject dragData = new DataObject("myObj", tagDragging);
    DragDrop.DoDragDrop(item, dragData, DragDropEffects.Move);
    }
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

神妖 2024-12-05 14:48:17

这是我过去使用过的代码:

private void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // Get ItemsControl for object being dragged
    if (sender is ItemsControl)
        _sourceItemsControl = sender as ItemsControl;
    else if (sender is Panel)
        _sourceItemsControl = WPFHelpers.FindAncester<ItemsControl>(sender as Panel);

    // Get ItemContainer for object being dragged
    FrameworkElement sourceItemsContainer = _sourceItemsControl
        .ContainerFromElement((Visual)e.OriginalSource) as FrameworkElement;

    // Get data object for object being dragged
    if (sourceItemsContainer == null)
        _draggedObject = _sourceItemsControl.DataContext;
    else if (sourceItemsContainer == e.Source)
        _draggedObject = e.Source;
    else
        _draggedObject = sourceItemsContainer.DataContext;

}

WPF Helper 类

public class WPFHelpers
{
    public static T FindAncester<T>(DependencyObject current)
    where T : DependencyObject
    {
        current = VisualTreeHelper.GetParent(current);

        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        };
        return null;
    }
}

Here's the code I've used in the past:

private void DragSource_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    // Get ItemsControl for object being dragged
    if (sender is ItemsControl)
        _sourceItemsControl = sender as ItemsControl;
    else if (sender is Panel)
        _sourceItemsControl = WPFHelpers.FindAncester<ItemsControl>(sender as Panel);

    // Get ItemContainer for object being dragged
    FrameworkElement sourceItemsContainer = _sourceItemsControl
        .ContainerFromElement((Visual)e.OriginalSource) as FrameworkElement;

    // Get data object for object being dragged
    if (sourceItemsContainer == null)
        _draggedObject = _sourceItemsControl.DataContext;
    else if (sourceItemsContainer == e.Source)
        _draggedObject = e.Source;
    else
        _draggedObject = sourceItemsContainer.DataContext;

}

WPF Helper class

public class WPFHelpers
{
    public static T FindAncester<T>(DependencyObject current)
    where T : DependencyObject
    {
        current = VisualTreeHelper.GetParent(current);

        while (current != null)
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        };
        return null;
    }
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文