UWP TreeView 在 treeView_Expanding 上加载元素的叶子会阻塞树
UWP TreeView loading leafs of element on treeView_Expanding does block the tree
团队,
我的数据结构有点复杂,。当我单击以展开项目时,即使我使用了 await/async,UI 也不会向我显示展开的元素,而是一直保留到创建所有叶子为止。
在非常大的子结构上,我希望打开它并看到要逐渐添加的项目。
我怀疑哪种行为更合适:
1) 如果在构建树时点击周围的使用,则在构建时显示叶子会出现问题。所以我不确定我喜欢这个
2) 由于这个过程可能需要一些时间,所以我想展示类似 "loading" 的内容或对正在发生的事情进行适当的视觉反馈。但是不知道怎么办。
你会推荐什么?
更多信息:
该项目有一个患者和每个患者下的访问。该结构是完全动态的,因此无法提前知道患者的级别数,因为每次访问都可以有子访问和与访问相关的文档。
患者人数可能会非常高 (10K+)。我遇到的第一个性能问题是一次加载所有患者和所有访问需要太多时间(> 1 分钟!)因此,根据一些指导,我采用了一种方法,其中只加载患者和一个空的如果患者有访问,则会创建叶子。
展开患者时,将加载该患者的所有叶子。深度和结构完全因患者而异。因此,有些加载速度非常快(1 级或总共访问次数很少),而另一些则需要 1 秒或更长时间,因为它们可以在 5 级或更多级上进行 50 次以上的访问。
当我使用 SQLServer Express 时,我已经检查过,从数据库中检索数据的查询没有相关影响,因为它们大约是几毫秒。
与 DB 的连接是通过 EFCore 完成的,叶子项是通过 LINQ 加载的,递归的等待 ToListAsync 更多:患者将加载连接到他的叶子。加载叶子时将查找并加载子叶子...子叶子将以相同的方式运行。
所以我没想到 UI 会有任何延误。
这里的代码用于加载访问过但尚未加载的患者的叶子
private async void treeView_Expanding(WinUI.TreeView sender, WinUI.TreeViewExpandingEventArgs args)
{
if (args.Item is MTreeViewPaz)
{
if ((((MTreeViewPaz)args.Item).VisitsN > 0) && (((MTreeViewPaz)args.Item).Loaded == LoadingStatus.NotStarted))
{
await ((MTreeViewPaz)args.Item).LoadDataAsync();
}
}
}
在叶子中应用完全相同的逻辑:
public async Task LoadDataAsync()
{
Loaded = LoadingStatus.Loading;
var aList = App.gDataContext.Cache.VVisitHierarchy
.Where(a => a.CodPaz == _PazV.CodPaz && a.Parent == null)
.OrderBy(b => b.CreationOrd).ThenBy(b => b.Data).ThenBy(b => b.CodPar)
.ToList();
foreach (var item in aList)
{
if (item.Visits > 0)
{
MTreeViewVisit aMVisit = new MTreeViewVisit(item);
Visits.Add(aMVisit);
if (item.Visits > 0)
{
await aMVisit.LoadDataAsync();
}
}
}
Visits.RemoveAt(0);
Loaded = LoadingStatus.Loaded;
}
我发现了这个:
var aList = await Task.Run(() => App.gDataContext.Cache.VVisitHierarchy
.Where(a => a.CodPaz == _PazV.CodPaz && a.Parent == null)
.OrderBy(b => b.CreationOrd).ThenBy(b => b.Data).ThenBy(b => b.CodPar)
.ToList());
解锁 UI 并允许在创建时显示叶子。
但是好用吗?
团队,
我的数据结构有点复杂,
我怀疑哪种行为更合适: 1) 如果在构建树时点击周围的使用,则在构建时显示叶子会出现问题。所以我不确定我喜欢这个 2) 由于这个过程可能需要一些时间,所以我想展示类似 "loading" 的内容或对正在发生的事情进行适当的视觉反馈。但是不知道怎么办。
你会推荐什么?
更多信息: 该项目有一个患者和每个患者下的访问。该结构是完全动态的,因此无法提前知道患者的级别数,因为每次访问都可以有子访问和与访问相关的文档。
患者人数可能会非常高 (10K+)。我遇到的第一个性能问题是一次加载所有患者和所有访问需要太多时间(> 1 分钟!)因此,根据一些指导,我采用了一种方法,其中只加载患者和一个空的如果患者有访问,则会创建叶子。 展开患者时,将加载该患者的所有叶子。深度和结构完全因患者而异。因此,有些加载速度非常快(1 级或总共访问次数很少),而另一些则需要 1 秒或更长时间,因为它们可以在 5 级或更多级上进行 50 次以上的访问。
当我使用 SQLServer Express 时,我已经检查过,从数据库中检索数据的查询没有相关影响,因为它们大约是几毫秒。
与 DB 的连接是通过 EFCore 完成的,叶子项是通过 LINQ 加载的,递归的等待 ToListAsync 更多:患者将加载连接到他的叶子。加载叶子时将查找并加载子叶子...子叶子将以相同的方式运行。
所以我没想到 UI 会有任何延误。
这里的代码用于加载访问过但尚未加载的患者的叶子
private async void treeView_Expanding(WinUI.TreeView sender, WinUI.TreeViewExpandingEventArgs args)
{
if (args.Item is MTreeViewPaz)
{
if ((((MTreeViewPaz)args.Item).VisitsN > 0) && (((MTreeViewPaz)args.Item).Loaded == LoadingStatus.NotStarted))
{
await ((MTreeViewPaz)args.Item).LoadDataAsync();
}
}
}
在叶子中应用完全相同的逻辑:
public async Task LoadDataAsync()
{
Loaded = LoadingStatus.Loading;
var aList = App.gDataContext.Cache.VVisitHierarchy
.Where(a => a.CodPaz == _PazV.CodPaz && a.Parent == null)
.OrderBy(b => b.CreationOrd).ThenBy(b => b.Data).ThenBy(b => b.CodPar)
.ToList();
foreach (var item in aList)
{
if (item.Visits > 0)
{
MTreeViewVisit aMVisit = new MTreeViewVisit(item);
Visits.Add(aMVisit);
if (item.Visits > 0)
{
await aMVisit.LoadDataAsync();
}
}
}
Visits.RemoveAt(0);
Loaded = LoadingStatus.Loaded;
}
我发现了这个:
var aList = await Task.Run(() => App.gDataContext.Cache.VVisitHierarchy
.Where(a => a.CodPaz == _PazV.CodPaz && a.Parent == null)
.OrderBy(b => b.CreationOrd).ThenBy(b => b.Data).ThenBy(b => b.CodPar)
.ToList());
解锁 UI 并允许在创建时显示叶子。 但是好用吗?