繁体   English   中英

C# WPF 拖放

[英]C# WPF Drag and Drop

有人可以推荐一个很好的拖放教程。

基础知识很容易找到,但它们并不能帮助我实现我需要的目标。 简而言之,我需要两个主面板,左边一个将包含多个堆栈面板(每个面板都具有水平方向)。 右边的将包含我想拖放到左边面板上的对象。 我想要实现的是,一旦我释放对象,我希望它成为面板的一部分,以便它与该面板中的其他对象“流动”。 此外,我希望它检测我是否位于两个已经存在的对象之间,因此将其放置在它们之间,将正确的对象移动一个位置。 反向操作也应该是可能的

感谢帮助

我有一些从旧项目中取出的代码,您可以使用它们来实现拖放行为。 它使用两个列表框,都启用了 AllowDrop 和一些事件来处理拖动。

测试数据:

var itemsInGroup1 = new ObservableCollection<MoveableItem>()
        {
            new MoveableItem {ID = 1, Name = "Item 1"},
            new MoveableItem {ID = 2, Name = "Item 2"},
            new MoveableItem {ID = 3, Name = "Item 3"},
        };

        var itemsInGroup2 = new ObservableCollection<MoveableItem>()
        {
            new MoveableItem {ID = 4, Name = "Item 4"},
            new MoveableItem {ID = 5, Name = "Item 5"},
            new MoveableItem {ID = 6, Name = "Item 6"},
        };

        List1.ItemsSource = itemsInGroup1;
        List2.ItemsSource = itemsInGroup2;

列表框:

<ListBox
        x:Name="List2"
        Grid.Column="2"
        Margin="30"
        AllowDrop="True"
        BorderBrush="DarkBlue"
        BorderThickness="2"
        Drop="List_OnDrop"
        PreviewMouseLeftButtonDown="List_OnPreviewMouseLeftButtonDown">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel>
                    <TextBlock Text="{Binding Name}" />
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

您使用 PreviewMouseLeftButtonDown 捕获 DragSource

public ListBox DragSource { get; set; }

private void List_OnPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        var listBox = (ListBox) sender;
        if (listBox == null) return;

        DragSource = listBox;

        object data = GetDataFromListBox(DragSource, e.GetPosition(listBox));
        if (data != null)
            DragDrop.DoDragDrop(listBox, data, DragDropEffects.Move);
    }

数据是通过对您单击的位置使用命中测试从 ListBox 中获取的。

private static object GetDataFromListBox(ListBox source, Point point)
    {
        if (source.InputHitTest(point) is UIElement element)
        {
            object data = DependencyProperty.UnsetValue;
            while (data == DependencyProperty.UnsetValue)
            {
                data = source.ItemContainerGenerator.ItemFromContainer(element);
                element = VisualTreeHelper.GetParent(element) as UIElement;

                if (element == source)
                    return null;

                if (data != DependencyProperty.UnsetValue)
                    return data;
            }
        }

        return null;
    }

最后,在 drop 事件中,您从源中删除项目并将其放置在目标中。

private void List_OnDrop(object sender, DragEventArgs e)
    {
        var target = (ListBox) sender;
        if (target.Name == DragSource.Name) return;

        var data = e.Data.GetData(typeof(MoveableItem));

        ((IList) DragSource.ItemsSource).Remove(data);
        ((IList) target.ItemsSource).Add(data);
    }

我没有解决您在对象之间检测的问题,因为我从中提取的代码库不需要该功能。 您可以通过订阅 ItemTemplate 上的 DragOver 来自己构建它,找出当前拖动的项目之间,然后在将其放入后重新排序集合。

更多信息: https : //docs.microsoft.com/en-us/dotnet/framework/wpf/advanced/drag-and-drop-overview

编辑:我找到了原始文章 - https://www.c-sharpcorner.com/uploadfile/dpatra/drag-and-drop-item-in-listbox-in-wpf/

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM