Windows Store App在ListView之间拖放

joe*_*lfp 2 listview windows-store-apps win-universal-app

我正在构建面向Windows 8.1和Windows 10的Windows应用商店应用/通用应用,我希望能够在ListView之间拖放项目,并能够将项目放在ListView中的特定位置.我遇到的主要问题是我找不到一个好方法来确定项目被删除的列表索引.

我发现了一个示例(XAML ListView重新排序)但重要的区别是我列表中的项目具有可变高度,因此此示例项目用于推断索引的简单计算对我来说不起作用.

我能够获得ListView中放置项目的位置的x,y位置,但是我无法使用该位置来计算索引.我发现有人使用ListView.GetItemAt(x,y)或ListView.HitTest(x,y),但正如其他人发现的那样,这些方法似乎不存在于Windows Universal应用程序中.我也尝试过使用VisualTreeHelper.FindElementsInHostCoordinates(),但我要么没有正确使用它,要么我不理解它的用途,因为我不能让它返回结果.

这是我尝试过的一些示例代码:

private void ListView_OnDrop(object sender, DragEventArgs e)
{
    var targetListView = (ListView)sender;

    var positionRelativeToTarget = e.GetPosition(targetListView);

    var rect = new Rect(positionRelativeToTarget, new Size(10, 15));
    var elements = VisualTreeHelper.FindElementsInHostCoordinates(rect, targetListView);

    // Trying to get the index in the list where the item was dropped
    // 'elements' is always empty
}
Run Code Online (Sandbox Code Playgroud)

作为参考,我使用的是C#,XAML和Visual Studio 2013.

谢谢!

小智 5

我找到了解决方案.我开发了一个Info Class来恢复丢弃新项目的索引.

public  class Info
{
    public int index { get; set; }
    public string color { get; set; }
}
Run Code Online (Sandbox Code Playgroud)

然后我定义了我的观察结果:

ObservableCollection<Info> c = new ObservableCollection<Info>();
c.Add(new Info { color = "#d9202b", index = 0 }); c.Add(new Info { color = "#ffffff", index = 1 }); 
c.Add(new Info { color = "#15c23c", index = 2 }); c.Add(new Info { color = "#c29b8f", index = 3 });
c.Add(new Info { color = "#0000ff", index = 4 }); c.Add(new Info { color = "#deba83", index = 5 });
Run Code Online (Sandbox Code Playgroud)

我也以同样的方式定义了另一个集合(c2).对于这个参议员,我将从第二个集合(c2)中拖出一个项目,我将把它放在第一个集合中(c)所以dragstarted我使用了这个:

private void x2_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
{
    strin = e.Items.FirstOrDefault() as Info;

    e.Data.Properties.Add("item", strin);
    e.Data.Properties.Add("gridSource", sender);
}
Run Code Online (Sandbox Code Playgroud)

要恢复有关我放置项目的位置的信息,应将其放在第一个列表中的项目上,因此我使用了以下内容:

private void x_Drop(object sender, DragEventArgs e)
{
    object gridSource;
    e.Data.Properties.TryGetValue("gridSource", out gridSource);
    if (gridSource == sender)
        return;
    object sourceItem;
    e.Data.Properties.TryGetValue("item", out sourceItem);
    //recuperate Info about place of dropped item
    Info p = ((FrameworkElement)e.OriginalSource).DataContext as Info;

    if(p==null)
    {
        //its not dropped over an item, lets add it in the end of the collection
        c2.Remove(sourceItem as Info);
        c.Add(sourceItem as Info);
    }
    else
    {
        //here we have information that we need
        c2.Remove(sourceItem as Info);
        c.Insert(p.index, sourceItem as Info);
        //c.Add(strin);
    }
    Reorder();
}
Run Code Online (Sandbox Code Playgroud)

然后我们应该在Reorder方法中为新项设置索引:

private void Reorder()
{
    for (int i = 0; i < c.Count; i++)
        c[i].index = i;
    for (int i = 0; i < c2.Count; i++)
        c2[i].index = i;
 }
Run Code Online (Sandbox Code Playgroud)