c# - ListView 拖放时未更新

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

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

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

当我运行应用程序并尝试将项目从一个 ListView 拖动到下一个 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 在其源发生更改时进行更新。

预先感谢所有阅读本文的人!

更新

我最近在 Shen Chauhan 的博客 ( http://www.shenchauhan.com/ ) 上发现了一个拖放示例,这让我稍微改变了我的 Drop 方法。现在,我不再尝试直接将删除的项目添加到 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); 
         }             
     }
}

最佳答案

IPLV_Drop任务,你有一个tasksToMove和一个 taskToMove (我看不到你在发布的代码中定义它的位置),并且你遍历了 taskIDtaskToMove然后在 tasks集合找到第一个与 taskID 匹配的集合.

您的_inProgressList_upcomingListObservableCollection<Tasks> ,当你对这两个集合进行操作时,该项的数据模型应该是 <Tasks> 。现在您可以从 MobileServiceCollection<Tasks, Tasks> tasks 获得一个项目,但你使用了 tasks = await taskTable.ToCollectionAsync();首先,所以该项目的数据模型发生了变化,但它应该是 Collection ,这不是<Tasks> .

When I run the app and attempt to drag an item from one ListView to the next, nothing happens on screen, however, the await UpdateTask(taskToMove) definitely runs properly, because I can see the Tasks table get updated in the database and the next time I run the app,...

所以我认为在 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?
    }
}

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

关于c# - ListView 拖放时未更新,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38044344/

相关文章:

c# - 泛型方法的可为空参数类型 <T>?

c# - Action<T> 委托(delegate)与与处置相关的事件处理程序

c# - 使用 HttpServer/HttpClient 集成测试 ASP.NET Web API 2;没有 HttpContext

c# - 在 WPF 中绘制相对于其容器的对角线 Text/TextBlock/Label/Control

javascript - 解析 JSON 并使用 jQuery mobile 中的数据扩展 ListView

c# - 用鼠标滚轮滚动 ListView 偶尔会取消滚动

c# - 如何为单个 MSTest 测试方法设置区域性?

xaml - 如何在 Xamarin Forms 中扩展一个内容 View 而另一个内容 View 具有固定高度

qt - 使用 ListView 的拖放功能来创建库存 UI

wpf - 我可以在 ControlTemplate 中的动画持续时间上使用数据绑定(bind)吗?