我有两个 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
(我看不到你在发布的代码中定义它的位置),并且你遍历了 taskID
在taskToMove
然后在 tasks
集合找到第一个与 taskID
匹配的集合.
您的_inProgressList
和_upcomingList
是 ObservableCollection<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/