ListView不会在拖放时更新

时间:2016-06-27 00:14:14

标签: c# xaml listview drag-and-drop uwp

我有两个ListView,我正在尝试设置拖放功能。每个ListView都是绑定到ObservableCollection(_upcomingList和_inProgressList)的数据,其中Tasks是我的模型之一。

我设置它的方式,当调用DragItemsStarting方法时,被拖动的项目的Id(从绑定到_upcomingList的ListView)存储在字符串中并设置为DataPackage。然后,当项目被删除在第二个ListView(绑定到_inProgressList)时,id从DataPackage中提取,我用它来搜索我的数据库中的完整条目。最后,项目的状态更改为“进行中”并添加到_inProgressList。

当我运行应用程序并尝试将项目从一个ListView拖到下一个时,屏幕上没有任何反应,但await UpdateTask(taskToMove)肯定正常运行,因为我可以看到任务表在数据库中得到更新当我下次运行应用程序时,我尝试拖动到进行中ListView的任务现在出现在那里。这是我的drop方法的实现(更新部分下面有一个更新的版本):

public async Task IPLV_Drop(object sender, DragEventArgs e)
{
    if (e.DataView.Contains(StandardDataFormats.Text))
    {
        var id = await e.DataView.GetTextAsync();
        var tasksToMove = id.Split(',');

        tasks = await taskTable.ToCollectionAsync();

        if (_inProgressList != null)
        {
            foreach (var taskId in tasksToMove)
            {
                var taskToMove = tasks.First(i => i.Id.ToString() == taskId);

                taskToMove.Status = "In Progress";

                _inProgressList.Add(taskToMove);
                _upcomingList.Remove(taskToMove);

                await UpdateTask(taskToMove);
            }
        }
    }
}

所有内容似乎都运行正常,所以我错过了沿线的某个步骤,让应用程序识别列表项何时从ObservableCollection中添加和删除,或者让ListViews在其源已更改时绑定更新。 / p>

提前感谢任何阅读此内容的人!

更新

我最近在Shen Chauhan的博客(http://www.shenchauhan.com/)上找到了一个拖放示例,这让我稍微改变了我的Drop方法。现在,我没有尝试直接将删除的项添加到我的ObservableCollection,而是创建了一个用ListView的itemsource填充的新集合,并将删除的项添加到该集合中。

更新后的Drop方法解决了InProgress ListView中没有出现丢弃项目的问题,但是,我仍然无法将待删除的项目从Upcoming ListView中删除。这是我目前存在的完整实现:​​

MainPage.xaml.cs中

public sealed partial class MainPage : Page
{
    MainPageViewModel vm = new MainPageViewModel();

    public MainPage()
    {
        InitializeComponent();
    }

    private void UpcomingListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e)
    {
        var tasks = string.Join(",", e.Items.Cast<Tasks>().Select(t => t.Id));
        e.Data.SetText(tasks);
        e.Data.RequestedOperation = DataPackageOperation.Move;
    }

    private void inProgressListView_DragOver(object sender, DragEventArgs e)
    {
        e.AcceptedOperation = (e.DataView.Contains(StandardDataFormats.Text)) ? DataPackageOperation.Move : DataPackageOperation.None;
    }

    private async void InProgressListView_Drop(object sender, DragEventsArgs e)
    {
        await vm.IPLV_Drop(sender, e);
    }
}

MainPageViewModel.cs

public class MainPageViewModel : ViewModelBase
{
    private MobileServiceCollection<Tasks, Tasks> tasks;
    private IMobileServiceSyncTable<Tasks> taskTable = App.MobileService.GetSyncTable<Tasks>();

    private ObservableCollection<Tasks> upcomingList = default(ObservableCollection<Tasks>);
    public ObservableCollection<Tasks> _upcomingList { get { return upcomingList; } set { Set(ref upcomingList, value); } }

    private ObservableCollection<Tasks> inProgressList = default(ObservableCollection<Tasks>);
    public ObservableCollection<Tasks> _inProgressList { get { return inProgressList; } set { Set(ref inProgressList, value); } }

     ...

     public async Task IPLV_Drop(object sender, DragEventArgs e)
     {
         var id = await e.DataView.GetTextAsync();
         var tasksToMove = id.Split(',');

         var inProgressListView = sender as ListView;
         var IPLVItemsSource = inProgressListView?.ItemsSource as ObservableCollection<Tasks>;

         tasks = await taskTable.ToCollectionAsync();

         foreach (var taskId in taskToMove)
         {
             var taskToMove = tasks.First(t => t.Id.ToString() == taskId);

             _upcomingList.Remove(taskToMove) // DOES NOT REMOVE ITEM

             taskToMove.Status = "In Progress";

             IPLVItemsSource.Add(taskToMove); // NOW WORKS

             await UpdateTask(taskToMove); 
         }             
     }
}

2 个答案:

答案 0 :(得分:2)

IPLV_Drop任务中,您有一个tasksToMove和一个taskToMove(我无法看到您在发布的代码中定义的位置),并且您遍历了{taskID 1}}在taskToMove中,然后在tasks集合中找到与taskID匹配的第一个。

您的_inProgressList_upcomingListObservableCollection<Tasks>,当您对这两个馆藏进行操作时,该项目的数据模型应为<Tasks>。现在您从MobileServiceCollection<Tasks, Tasks> tasks获得了一个项目,但您首先使用了tasks = await taskTable.ToCollectionAsync();,因此项目的数据模型已更改,但它应该是Collection,它不是<Tasks>

  

当我运行应用程序并尝试将项目从一个ListView拖到下一个时,屏幕上没有任何反应,但是,等待UpdateTask(taskToMove)肯定正常运行,因为我可以看到任务表在数据库中得到更新下次我运行应用程序,...

所以我认为在foreach (var taskId in taskToMove)中找到的项目只能用于数据库操作,如果你想刷新UI,你可能需要这样的代码:

public async Task IPLV_Drop(object sender, DragEventArgs e)
{
    var id = await e.DataView.GetTextAsync();
    var tasksToMove = id.Split(',');
    foreach(var taskToMove in tasksToMove)
    {
        __inProgressList.Add(taskToMove);
        _upcomingList.Remove(taskToMove);
    }


    //var inProgressListView = sender as ListView;
    //var IPLVItemsSource = inProgressListView?.ItemsSource as ObservableCollection<DataModel>;

    tasks = await taskTable.ToCollectionAsync();

    foreach (var taskId in taskToMove)
    {
        var taskToMove = tasks.First(t => t.Id.ToString() == taskId);

        //_upcomingList.Remove(taskToMove) // DOES NOT REMOVE ITEM

        taskToMove.Status = "In Progress";

        //IPLVItemsSource.Add(taskToMove); // NOW WORKS

        await UpdateTask(taskToMove); //this used for update database?
    }
}

由于我无法使用您的代码段重现您的问题,如果您在此处有任何问题,请发表评论。

答案 1 :(得分:0)

所以我能够在我对@ GraceFeng-MSFT的评论中提到这一点。对于可能遇到此问题的其他任何人,我的最终解决方案最终看起来像是对 MainPAge.xaml.cs InProgressListView_Drop()中的IPLV_Drop()进行了一些小调整。强> MainPageViewModel.cs

private async void InProgressListView_Drop(object sender, DragEventArgs e)
{
    ObservableCollection<Tasks> sourceListView = upcomingListView?.ItemsSource as ObservableCollection<Tasks>;

    await vm.IPLV_Drop(sourceListView, sender, e);
}
public async Task IPLV_Drop(ObservableCollection<Tasks> source, object sender, DragEventArgs e)
{
    var id = await e.DataView.GetTextAsync();
    var tasksToMove = id.Split(',');

    var inProgressListView = sender as ListView;
    var IPLVItemsSource = inProgressListView?.ItemsSource as ObservableCollection<Tasks>;

    ObservableCollection<Tasks> test = source; // TODO: Change var name

    if (IPLVItemsSource != null)
    {
        foreach (var taskId in tasksToMove)
        {
            var taskToMove = test.First(I => i.Id.ToString() == taskId);

            source.Remove(taskToMove);

            taskToMove.Status = "In Progress";
            IPLVItemsSource.Add(taskToMove);

            await UpdateTask(taskToMove);
            await RefreshTasks();
        }
    }
}