C # WPF Drag and Drop - PullRequest
       0

C # WPF Drag and Drop

0 голосов
/ 09 ноября 2018

Может ли кто-нибудь порекомендовать хороший учебник для перетаскивания.

Основы легко найти, но они мало помогают мне в достижении цели, которая мне нужна. В двух словах, мне нужны две основные панели, левая будет содержать несколько панелей стека (каждая из них будет иметь горизонтальную ориентацию). Правый будет содержать объекты, которые я хочу перетащить на панели слева. То, чего я хочу достичь, - это после того, как я отпущу объект, я хочу, чтобы он стал частью панели, чтобы он «сливался» с другими объектами на этой панели. Также я хочу, чтобы он обнаружил, что я нахожусь между двумя уже существующими объектами, поэтому он помещается между ними, перемещая нужные на одну позицию. Обратная операция также должна быть возможной

Спасибо за помощь

1 Ответ

0 голосов
/ 09 ноября 2018

У меня есть некоторый код, который я вынул из старого проекта, который вы можете использовать для достижения поведения перетаскивания. Он использует два списка, оба с включенным 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:

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

Вы захватываете DragSource, используя PreviewMouseLeftButtonDown

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;
    }

Наконец, в случае выпадения вы удаляете элемент из источника и помещаете его в цель.

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);
    }

Я не рассмотрел вашу проблему обнаружения между объектами, поскольку кодовая база, из которой я извлек это, не требовала такой функциональности. Вы можете создать это в себе, подписавшись на DragOver на ItemTemplate, выяснить, между какими объектами в данный момент находится перетаскивание, и затем переупорядочить коллекцию после ее размещения.

Больше здесь: 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 /

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...