在 ContextFlyout 打开之前或项目被拖动之前选择项目
在 ContextFlyout 打开之前或项目被拖动之前选择项目
我有一个带有上下文菜单并且可重新排序的 ListView。
我希望它的行为非常类似于幻灯片演示中的缩略图(以及许多其他应用程序):
- 如果你右击一个尚未被选中的页面,那么在上下文菜单弹出之前,它将成为选中的页面。
- 如果你开始拖动一个尚未被选中的页面,那么在拖动之前,它将成为选中的页面。
Xaml代码:
代码:
namespace TestApp { public class DocPage { public string Name; // 编辑:实际类更复杂,包括渲染的位图缩略图等... } public sealed partial class MainPage : Windows.UI.Xaml.Controls.Page { public ObservableCollectionPages = new ObservableCollection (); public MainPage() { this.InitializeComponent(); DocPage PageA = new DocPage() { Name = "页面A" }; DocPage PageB = new DocPage() { Name = "页面B" }; Pages.Add(PageA); Pages.Add(PageB); // 故意添加重复项,我们无法通过“item”来区分选择 Pages.Add(PageB); Pages.Add(PageA); Pages.Add(PageB); Pages.Add(PageB); } } }
如何实现这个功能?
编辑:满足预期行为的一种方法是,当按下项时触发 ListView 的选择/多选逻辑(使用 ctrl / shift),而不是在释放时触发。显然,在 WPF 中,选择逻辑发生在按下项时,但在 UWP 中,这发生在释放项时,不确定为什么(链接)。
问题的原因是在弹出上下文菜单或拖动项目之前,需要先选择项目。解决方法是在ListView的RightTapped事件和DragItemsStarting事件中获取当前点击或拖动的项,并将其设置为选中状态。此外,建议使用具有特定id的类实例来替代普通值作为ListView的项。
为了解决这个问题,我们可以使用以下代码:
private void MyListView_RightTapped(object sender, RightTappedRoutedEventArgs e) { ListView listView = (ListView)sender; DocPage targetItem = ((FrameworkElement)e.OriginalSource).DataContext as DocPage; var index = Pages.IndexOf(targetItem); if (index >= 1 && index < Pages.Count) { MyListView.SelectedIndex = index; } } private void ListView_DragItemsStarting(object sender, DragItemsStartingEventArgs e) { if (e.Items.Count == 1) { DocPage targetItem = e.Items[0] as DocPage; var index = Pages.IndexOf(targetItem); if (index >= 1 && index < Pages.Count) { MyListView.SelectedIndex = index; } } }
在XAML中,我们需要将ListView的SelectionChanged和DragItemsStarting事件与对应的方法关联起来:
此外,根据问题中的回复,我们可以使用具有特定id的类实例来解决重复项的问题。这样,我们可以通过id来区分选中的项。
希望这篇文章能帮助你解决ListView中选择项目的问题。