Gong Solutions Перетащите, чтобы отсортировать список, удалив элементы из списка - PullRequest
0 голосов
/ 21 декабря 2018

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

Когда я удаляю атрибут dd:DragDrop.DropHandler="{Binding}", перетаскивание по интерфейсу работает нормально.Тем не менее, мне нужно вызвать событие, чтобы я знал, когда список был переупорядочен.

XAML:

<Window x:Class="Reorder_item_WPF.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" 
        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
        xmlns:dd="clr-namespace:GongSolutions.Wpf.DragDrop;assembly=GongSolutions.Wpf.DragDrop">
    <Grid>
        <ListBox Grid.Column="1" SelectionMode="Extended" ItemsSource="{Binding MSPCollection}"
                 dd:DragDrop.IsDragSource="True" Width="300" Margin="0,0,5,0" 
                 dd:DragDrop.IsDropTarget="True"
                 dd:DragDrop.DropHandler="{Binding}">

            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Grid Background="#2ba3d5" Height="50" Width="280">
                        <TextBlock Drop="TextBlock_Drop" Text="{Binding Name}" 
                                   Foreground="White" 
                                   HorizontalAlignment="Center" 
                                   VerticalAlignment="Center" 
                                   FontSize="40"/>
                    </Grid>                    
                </DataTemplate>             
            </ListBox.ItemTemplate>
        </ListBox>
    </Grid>
</Window>

C #:

public class MSP {
    public int Id { get; set; }
    public string Name { get; set; }        
}

class MainViewModel : IDropTarget
{
    public ObservableCollection<MSP> MSPCollection { get; set; }

    public MainViewModel() {
        MSPCollection = new ObservableCollection<MSP>();

        MSPCollection.Add(new MSP() { 
            Id = 1,
            Name = "Anis Derbel"
        });

        MSPCollection.Add(new MSP()
        {
            Id = 2,
            Name = "Firas Mdimagh"
        });

        MSPCollection.Add(new MSP()
        {
            Id = 3,
            Name = "Khaled Jemni"
        });

        MSPCollection.Add(new MSP()
        {
            Id = 4,
            Name = "Sahbouch"
        });        
    }

    public void DragOver(IDropInfo dropInfo) {
        if (dropInfo.Data is MSP) {
            dropInfo.DropTargetAdorner = DropTargetAdorners.Highlight;
            dropInfo.Effects = DragDropEffects.Move;
        }
    }

    public void Drop(IDropInfo dropInfo) {
        MSP msp = (MSP)dropInfo.Data;
        ((IList)dropInfo.DragInfo.SourceCollection).Remove(msp);
    }
}

1 Ответ

0 голосов
/ 21 декабря 2018

DragOver не удаляет никаких предметов.Вы удаляете предметы методом Drop.Вы не должны выполнять удаление или добавление в методе DragOver, для этого и нужен метод Drop.DragOver следует использовать только для установки целевого украшения и эффектов.Я использовал ILSpy для просмотра их кода (см. Ниже), и это помогло пролить некоторый свет на то, что здесь происходит.У них есть класс с именем DefaultDropHandler : IDropTarget, который, как следует из названия, является обработчиком удаления по умолчанию, если он не назначен с использованием присоединенного свойства dd:DragDrop.DropHandler.Поэтому, когда вы удаляете строку dd:DragDrop.DropHandler="{Binding}", это то, что используется для операции удаления.Глядя на их код, все обрабатывается для вас, то есть элемент добавляется и удаляется, с целым рядом ошибок и проверок индекса на этом пути.

Когда вы действительно установите обработчик отбрасывания какваша ViewModel, ни один из кодов в обработчике по умолчанию не выполняется, так как вы заменили этот обработчик с вашей ViewModel.Таким образом, вы должны полностью справиться с падением.Другими словами, вы должны выполнить всю проверку ошибок и типов, удалить элементы и добавить элементы (если у вас более одного списка) и сохранить правильный порядок.Вы также можете проверить, что исходная коллекция не совпадает с целевой коллекцией, прежде чем выполнять какие-либо операции удаления и добавления, но это все равно не добавит их в правильные позиции.

Поскольку у вас есть толькоодин список, не удаляйте элемент в методе Drop.Но ничего не произойдет по причинам, которые я изложил выше.Если у вас есть более одного списка, вот как вы бы перемещали элементы из одного списка в другой:

public void Drop(IDropInfo dropInfo) 
{
    MSP msp = (MSP)dropInfo.Data;
    if(dropInfo.DragInfo.SourceCollection != dropInfo.TargetCollection)
    {
        ((IList)dropInfo.DragInfo.SourceCollection).Remove(msp);
        ((IList)dropInfo.TargetCollection).Add(msp);
    }
}

Вы должны будете выполнить работу по поддержанию элементов в правильном порядке, если этоэто то, что вам нужно.В качестве альтернативы выполнению всей этой работы вы можете использовать и расширить их обработчик по умолчанию.Они создали Drop метод virtual, так что вы можете сделать так, чтобы ваша модель представления наследовала от DefaultDropHandler
(т.е. class MainViewModel : DefaultDropHandler) вместо реализации интерфейса IDropTarget.Затем просто переопределите метод Drop и вызовите базовый метод.Примерно так:

public override void Drop(IDropInfo dropInfo)
{
    base.Drop(dropInfo);
    //do other stuff
}

Вы также можете переопределить метод DragOver таким же образом, если вам нужно, но если вы этого не сделаете, он просто будет использовать поведение по умолчанию.

Дополнительная информация

Если вам интересно, вот обработчик по умолчанию, который использует Гун, когда вы его не назначаете:

public virtual void Drop(IDropInfo dropInfo)
{
    if (dropInfo != null && dropInfo.DragInfo != null)
    {
        int insertIndex = (dropInfo.InsertIndex != dropInfo.UnfilteredInsertIndex) ? dropInfo.UnfilteredInsertIndex : dropInfo.InsertIndex;
        ItemsControl itemsControl = dropInfo.VisualTarget as ItemsControl;
        if (itemsControl != null)
        {
            IEditableCollectionView editableItems = itemsControl.Items;
            if (editableItems != null)
            {
                NewItemPlaceholderPosition newItemPlaceholderPosition = editableItems.NewItemPlaceholderPosition;
                if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtBeginning && insertIndex == 0)
                {
                    insertIndex++;
                }
                else if (newItemPlaceholderPosition == NewItemPlaceholderPosition.AtEnd && insertIndex == itemsControl.Items.Count)
                {
                    insertIndex--;
                }
            }
        }
        IList destinationList = dropInfo.TargetCollection.TryGetList();
        List<object> data = ExtractData(dropInfo.Data).OfType<object>().ToList();
        List<object>.Enumerator enumerator;
        if (!ShouldCopyData(dropInfo))
        {
            IList sourceList = dropInfo.DragInfo.SourceCollection.TryGetList();
            if (sourceList != null)
            {
                enumerator = data.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext())
                    {
                        object o2 = enumerator.Current;
                        int index = sourceList.IndexOf(o2);
                        if (index != -1)
                        {
                            sourceList.RemoveAt(index);
                            if (destinationList != null && object.Equals(sourceList, destinationList) && index < insertIndex)
                            {
                                insertIndex--;
                            }
                        }
                    }
                }
                finally
                {
                    ((IDisposable)enumerator).Dispose();
                }
            }
        }
        if (destinationList != null)
        {
            TabControl tabControl = dropInfo.VisualTarget as TabControl;
            bool cloneData = dropInfo.Effects.HasFlag(DragDropEffects.Copy) || dropInfo.Effects.HasFlag(DragDropEffects.Link);
            enumerator = data.GetEnumerator();
            try
            {
                while (enumerator.MoveNext())
                {
                    object o = enumerator.Current;
                    object obj2Insert = o;
                    if (cloneData)
                    {
                        ICloneable cloneable = o as ICloneable;
                        if (cloneable != null)
                        {
                            obj2Insert = cloneable.Clone();
                        }
                    }
                    destinationList.Insert(insertIndex++, obj2Insert);
                    if (tabControl != null)
                    {
                        TabItem obj = tabControl.ItemContainerGenerator.ContainerFromItem(obj2Insert) as TabItem;
                        if (obj != null)
                        {
                            obj.ApplyTemplate();
                        }
                        tabControl.SetSelectedItem(obj2Insert);
                    }
                }
            }
            finally
            {
                ((IDisposable)enumerator).Dispose();
            }
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...