如何解决允许动态项目大小、重新排序和虚拟化的 WinUI 列表控件
我正在尝试在 WinUI/UWP 应用程序中实现类似于 Notion 或 Craft 的文档编辑器。这些应用程序不使用“单字段”编辑器(如 MS Word 那样),而是显示垂直堆栈的内容行(所谓的“块”),其中可以包含文本、媒体、链接预览、LaTeX 等。这些行可以通过侧面的 ::
手柄重新排列:
所以我一直在寻找一些列表/堆栈控件:
我不需要的功能:标题、列、排序、过滤。我已经查看了 WinUI 2.x 和 Windows Community Toolkit 中的以下控件,但似乎每个控件都缺少一项或多项必需的功能。
ListView
它似乎是带有拖放功能的列表的首选控件,但它无法动态调整项目的大小。此外,它的拖动使用了整个项目区域,而我只需要让它在侧面带有 ::
句柄即可使用。
ItemsStackPanel
支持虚拟化的 StackPanel 版本,但据我所知,面板应该用于子项的简单布局,而不是用于呈现基于数据源的长列表。
VariableSizedWrapGrid
这是唯一正式声明支持可变大小项目的列表/网格控件,但同时不支持虚拟化。但是,我发现了一个 solution from 2013,它基于预先计算不可见元素的内容大小。
ItemsRepeater
一个非常基本的控件,它本身不提供虚拟化:“ItemsRepeater 在连接到支持虚拟化的主机时支持虚拟化。”
DataGrid
来自 WCT 的相当重的控制似乎是唯一一个 dynamically resize cells 取决于其内容。不幸的是,它不允许行重新排序(只能排序),所以我也不能使用它。
我错过了什么吗?如果没有,我想知道哪个是最好的基础。谢谢!
解决方法
我不得不说没有任何控件可以满足所有要求。实际上,::是用来控制darg指定项的,你可以在ListView控件中实现类似的行为。
ListView 允许您通过将 CanReorderItems
和 AllowDrop
属性设置为 True 来轻松地对 ListView 内的项目重新排序。如果您不想让用户拖动特定项目,您可以将 CanDragItems
属性设置为 True,并为 DragItemsStarting
事件添加事件处理程序。对于事件处理程序,您可以检查任何条件,然后如果要取消拖动操作,只需将事件参数的 Cancel 属性设置为 true。如下:
XML 代码:
<ListView x:Name="TargetListView"
CanReorderItems="True" CanDragItems="True" AllowDrop="True" DragItemsStarting="TargetListView_DragItemsStarting">
<ListViewItem>
<TextBlock x:Name="item1" Text="item1"/>
</ListViewItem>
<ListViewItem >
<TextBlock x:Name="item2" Text="item2"/>
</ListViewItem>
<ListViewItem>
<TextBlock x:Name="item3" Text="item3"/>
</ListViewItem>
</ListView>
背后的代码:
private void TargetListView_DragItemsStarting(object sender,DragItemsStartingEventArgs e)
{
e.Cancel = e.Items.Any(o =>
{
if (o is TextBlock t && t.Name.ToString() == "item2")
return true;
return false;
});
}
可以看到,ListView中有3个textBlock,item2的textblock的拖动动作会受到限制。
,事实证明,ListView
可以动态调整其项目的大小 - 只需要将 StackPanel
放入 ListViewItem
中,因为堆栈会“推送”其父级的大小向外。正如this answer所说:
Grid
和 RelativePanel
等容器控件会自动缩放到其父元素的完整可用大小,而其他类似 StackPanel
的容器控件只会扩展到其子元素所需的最小大小。>
此外,在 TextBox
内添加 ListViewItem
会使用文本输入行为覆盖拖动行为,但列表项仍可拖动到文本框外。我可以保持原样,也可以按照 Arya's answer 将可拖动区域缩小到 ::
句柄。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。