Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 当PreviewMouseLeftButtonDown命令RelayCommand\EventToCommand激发时,在ItemsControl中查找选定项_C#_Wpf_Mvvm_Eventtocommand - Fatal编程技术网

C# 当PreviewMouseLeftButtonDown命令RelayCommand\EventToCommand激发时,在ItemsControl中查找选定项

C# 当PreviewMouseLeftButtonDown命令RelayCommand\EventToCommand激发时,在ItemsControl中查找选定项,c#,wpf,mvvm,eventtocommand,C#,Wpf,Mvvm,Eventtocommand,我的应用程序是wpf mvvm,为事件使用RelayCommand\EventToCommand绑定。我的应用程序执行一些典型的从列表框到ItemsControl的拖放操作(它实际上是一个顶部有ItemsControl的图像控件,用于保存拖放的项目)。列表框中填充了vm ObservableCollection。ItemsControl也是一个ObservableCollection,我将删除的MyObj项插入其中 当我从列表框中拖动项目并将其放到\on\ItemsControl\image中时

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

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

vm C#:

PreviewMouseLeftButtonDownCommand=新建RelayCommand(e=>
{
如果(例如,来源是列表框)
{
//获取拖动的列表框项
ListBox ListBox=e.源为ListBox;
ListBoxItem ListBoxItem=VisualHelper.FindAncestor((DependencyObject)e.OriginalSource);
//查找listBoxItem后面的数据
if(listBox==null | | listBoxItem==null)返回;
MyObj标记=(MyObj)listBox.ItemContainerGenerator.ItemFromContainer(listBoxItem);
//初始化拖放操作
DataObject dragData=新的DataObject(“myObj”,标记);
DragDrop.DoDragDrop(listBoxItem、dragData、DragDropEffects.Move);
}
else if(例如,源为ItemsControl)
{
ItemsControl ItemsControl=e.源作为ItemsControl;
对象项=VisualHelper.FindAncestor((DependencyObject)e.OriginalSource);
if(itemsControl==null | | item==null)返回;
MyObj标记=(MyObj)itemsControl.ItemContainerGenerator.ItemFromContainer(项);
//初始化拖放操作
DataObject dragData=新数据对象(“myObj”,tagdraging);
DragDrop.DoDragDrop(物品,dragData,DragDropEffects.Move);
}
});

以下是我过去使用过的代码:

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;

}
private void DragSource\u PreviewMouseLeftButtonDown(对象发送器,鼠标按钮ventargs e)
{
//获取要拖动的对象的ItemsControl
如果(发件人是ItemsControl)
_sourceItemsControl=发件人作为ItemsControl;
否则,如果(发送方为面板)
_sourceItemsControl=WPFHelpers.FindAncester(发送方作为面板);
//获取要拖动的对象的ItemContainer
FrameworkElement sourceItemsContainer=\u sourceItemsControl
.ContainerRomeElement((可视)例如OriginalSource)作为框架元素;
//获取要拖动的对象的数据对象
if(sourceItemsContainer==null)
_draggedObject=\u sourceItemsControl.DataContext;
else if(sourceItemsContainer==e.Source)
_draggedObject=e.震源;
其他的
_draggedObject=sourceItemsContainer.DataContext;
}
WPF助手类

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;
    }
}
公共类WPFHelpers
{
公共静态T FindAncester(DependencyObject当前)
其中T:DependencyObject
{
当前=VisualTreeHelper.GetParent(当前);
while(当前!=null)
{
如果(电流为T)
{
返回(T)电流;
}
当前=VisualTreeHelper.GetParent(当前);
};
返回null;
}
}

P.S.我读了一篇关于使用鼠标点击点查找项目的相关文章。我确实用它工作,但它看起来像一个hak,所以我在寻找另一个建议。ItemsControl没有SelectedItem的概念。因此,在单击鼠标左键时,必须使用鼠标的位置。是否可以使用模板化列表框而不是ItemsControl?如果有一种方法允许用户将项目放置在列表框的任何位置,并且列表框允许在该位置呈现被放置的项目,那么这将是一种可行的解决方案。当我尝试此操作时,列表框会不断创建项目列表,并且不允许从某个点(x&y co ord)放置项目。关于如何更改\自定义列表框(或任何其他ItemsControl派生控件)呈现其项目的方式有何想法?我想这可能是你的幸运日。我上星期才碰到这个。请看这篇文章,看看它是否有帮助:我相信您有一个输入错误:您使用“sourceObjectContainer”和“sourceObjectContainer”来引用同一个对象。@Mick谢谢,它已经更新了。您的拼写错误更正中有一个拼写错误:)我花了一分钟才明白您指的是
sourceItemsContainer
sourceObjectContainer
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;
    }
}