拖放时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);
}
}
}
在IPLV_Drop
任务中,您有tasksToMove
和taskToMove
(我看不到您在发布的代码中定义的位置),并且您在taskToMove
中遍历taskID
,然后在tasks
集合中找到与taskID
匹配的第一个。
你的_inProgressList
和_upcomingList
是ObservableCollection<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 .cs和MainPageViewModel.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();
}
}
}