拖放时ListView不更新

本文关键字:更新 ListView 拖放 | 更新日期: 2023-09-27 17:49:24

我有两个ListViews,我试图设置拖放功能。每个ListView的数据绑定到一个ObservableCollection (_upcomingList和_inProgressList),其中任务是我的模型之一。

我设置它的方式是,当调用DragItemsStarting方法时,被拖动的项目的Id(从绑定到_upcomingList的ListView)存储在字符串中并设置为DataPackage。然后,在第二个ListView(绑定到_inProgressList)中删除项目时,从DataPackage中提取id,并使用它来搜索数据库中的完整条目。最后,项目的状态更改为'In Progress'并添加到_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中添加和删除时,或者当列表视图的源发生变化时,它们的绑定更新。

提前感谢任何读到这篇文章的人!

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

更新的Drop方法解决了未出现在InProgress ListView中的掉落项目的问题,但是,我仍然有麻烦从即将到来的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); 
         }             
     }
}

拖放时ListView不更新

IPLV_Drop任务中,您有tasksToMovetaskToMove(我看不到您在发布的代码中定义的位置),并且您在taskToMove中遍历taskID,然后在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?
    }
}

由于我无法使用您的代码片段重现您的问题,如果您在这里有任何问题,请留下评论

所以我能够弄清楚,正如我在@GraceFeng-MSFT的评论中提到的。对于其他可能有这个问题的人,这是我最终的解决方案,包括对 mainpage . example .csMainPageViewModel.cs中的InProgressListView_Drop()IPLV_Drop()的一些小调整:

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