簡體   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