GongSolutions DragDrop между двумя представлениями списка, а также в пределах одного представления списка - PullRequest
0 голосов
/ 13 апреля 2020

У меня есть два представления списка в моем приложении WPF, и они связаны со списками двух разных типов экземпляров классов.

ListView1:

public class DataInt
{
    public int Value { get; set; }
}

ListView2:

public class DataStr
{
    public string Value { get; set; }
}

Эти два класса связаны, и у меня есть метод, который преобразует DataInt в DataStr. Для простоты, скажем, это выглядит так:

private static DataStr ConvertIntToStr(DataInt val)
{
    return new DataStr() { Value = "$" + val.Value };
}

Я хочу иметь возможность перетаскивать элементы из ListView1 в ListView2 (меня не волнует обратное), и важно, чтобы я мог перетащите несколько элементов одновременно. Я также хочу иметь возможность переупорядочивать элементы в ListView2.

Я использую библиотеку перетаскивания GongSolutions для этой .

Я получил первую часть для работы, с некоторая помощь от здесь . Вот как выглядит мой код. Я использую шаблон MVVM (с MVVM Light).

public class MainViewModel : ViewModelBase, IDropTarget
{
    private ObservableCollection<DataInt> ints;
    public ObservableCollection<DataInt> Ints { get { return ints; } set { Set(ref ints, value); } }
    private ObservableCollection<DataStr> strs;
    public ObservableCollection<DataStr> Strs { get { return strs; } set { Set(ref strs, value); } }

    public MainViewModel(IDataService dataService)
    {
        Ints = GetIntData();
        Strs = GetStringData();
    }

    void IDropTarget.DragOver(IDropInfo dropInfo)
    {
        if (dropInfo.Data is DataInt || dropInfo.Data is IEnumerable<object>)
        {
            dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
            dropInfo.Effects = DragDropEffects.Copy;
        }
    }

    void IDropTarget.Drop(IDropInfo dropInfo)
    {
        if (dropInfo.Data is DataInt)
        {
            Strs.Add(ConvertIntToStr((dropInfo.Data as DataInt)));
        }
        else if (dropInfo.Data is IEnumerable<object>)
        {
            var data = dropInfo.Data as IEnumerable<object>;
            foreach (var item in data)
            {
                var intVal = item as DataInt;
                Strs.Add(ConvertIntToStr(intVal));
            }
        }
    }

    private static DataStr ConvertIntToStr(DataInt val)
    {
        return new DataStr() { Value = "$" + val.Value };
    }

    private ObservableCollection<DataInt> GetIntData()
    {
        var data = new ObservableCollection<DataInt>();
        foreach (var i in Enumerable.Range(1, 10))
        {
            data.Add(new DataInt() { Value = i });
        }
        return data;
    }

    public ObservableCollection<DataStr> GetStringData()
    {
        var data = new ObservableCollection<DataStr>();
        foreach (var i in Enumerable.Range(100, 10))
        {
            data.Add(new DataStr() { Value = "$" + i.ToString() });
        }
        return data;
    }
}

My XAML довольно прост

<ListView Name="ListView1" Grid.Column="0" Margin="8"
          ItemsSource="{Binding Ints}" DisplayMemberPath="Value"
          gong:DragDrop.IsDragSource="True"
          gong:DragDrop.IsDropTarget="False"
          gong:DragDrop.UseDefaultDragAdorner="True"/>
<ListView Name="ListView2" Grid.Column="1" Margin="8"
          ItemsSource="{Binding Strs}" DisplayMemberPath="Value"
          gong:DragDrop.IsDragSource="True"
          gong:DragDrop.IsDropTarget="True"
          gong:DragDrop.UseDefaultDragAdorner="True"
          gong:DragDrop.DropHandler="{Binding}"/>

Это отлично работает, и я могу перетаскивать (один или несколько элементов) из ListView1 в ListView2. Но это не позволит мне перетащить (переставить) ListView2. Поэтому я попытался изменить код на следующий, и при отладке я вижу, что он действительно go внутри раздела else. Но он все еще не переставляет элементы.

void IDropTarget.DragOver(IDropInfo dropInfo)
{
    if (dropInfo.Data is DataInt || dropInfo.Data is IEnumerable<object>)
    {
        dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
        dropInfo.Effects = DragDropEffects.Copy;
    }
    else if (dropInfo.Data is DataStr)
    {
        dropInfo.DropTargetAdorner = DropTargetAdorners.Insert;
        dropInfo.Effects = DragDropEffects.Move;
    }
}

Я что-то здесь упускаю?

...