我创建了IOrderedIEnumerable
的扩展程序
看起来像这样:
internal static ObservableCollection<T> ToObservableCollection<T>(this IOrderedEnumerable<T> list)
{
var observableCollection = new ObservableCollection<T>();
foreach (var p in list)
observableCollection.Add(p);
return observableCollection;
}
我还有一个看起来像这样的页面:
private ObservableCollection<BusStopName> _ListOfBusStopNames;
public BusStopsListPage()
{
this.InitializeComponent();
this.SetIsBackFromPageAllowed(true);
_ListOfBusStopNames = Timetable.Instance.BusStopsNames
.OrderBy(p => p.Name)
.ToObservableCollection<BusStopName>();
}
在此页面中,我有一个与_ListOfBusStopNames
Timetable.Instance.BusStopsNames
有2812个条目。
当我导航到此页面时,应用程序内存正在增长到无穷大数字。看起来像(红线是导航到此页面的时刻):
我不知道它是什么。 有人有任何想法吗?
当我将实例构造函数更改为:
时public BusStopsListPage()
{
this.InitializeComponent();
this.SetIsBackFromPageAllowed(true);
_ListOfBusStopNames = new ObservableCollection<BusStopName>();
}
一切都很好。此外,当我在此构造函数中手动将List
(Timetable.Instance.BusStopsNames
)更改为ObservableCollection
时,它的效果也很好。
修改 嗯..我试图做一个例子如何重现它,我得到一个解决方案。这是非常令人困惑的,所以如果有人能解释为什么会发生这种情况会很好:)
<Frame Name="MainFrame" />
this.Loaded += (s, e) => MainFrame.Navigate(typeof(BlankPage1));
BlankPage1
在BlankPage视图中添加:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<StackPanel>
<ListView ItemsSource="{x:Bind _ListOfTestClasses}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:TestClass">
<Grid>
<TextBlock Text="{x:Bind Name}" />
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
</Grid>
在代码隐藏中:
public sealed partial class BlankPage1 : Page
{
private List<TestClass> _List;
private ObservableCollection<TestClass> _ListOfTestClasses;
public BlankPage1() {
this.InitializeComponent();
GenerateTestData();
_ListOfTestClasses = _List.OrderBy(p => p.Name).ToObservableCollection<TestClass>();
}
private void GenerateTestData() {
_List = new List<TestClass>();
for(int i = 0; i < 2800; i++)
_List.Add(new TestClass() { Id = i, Name = Guid.NewGuid().ToString() });
}
}
public static class Extension {
public static ObservableCollection<T> ToObservableCollection<T>(this IOrderedEnumerable<T> list) {
var observableCollection = new ObservableCollection<T>();
foreach (var p in list)
observableCollection.Add(p);
return observableCollection;
}
}
public class TestClass {
public int Id { get; set; }
public string Name { get; set; }
}
运行应用
所以..你可以看到应用程序滞后,内存占用越来越多..现在......尝试删除BlankPage1
视图StackPanel
。现在运行应用程序。
答案 0 :(得分:1)
这是一个常见问题。问题是在XAML中滥用面板。 Grid
将伸展以适应其容器的边界,并将其级联到其子级。 StackPanel
只会级联相反方向的大小。
例如,当您有<StackPanel Orientation="Vertical"/>
时,所有孩子都会获得父Grid
的宽度,但不会获得高度。因为方向是垂直的,所以高度将是无限的,以允许面板根据其请求的高度堆叠其子节点。
如果您有<StackPanel Orientation="Horizontal"/>
,则所有孩子都会获得父Grid
的高度,但不会获得宽度。与上述相同的原因。它需要水平堆叠。
所以...... ,当<ListView/>
内有<StackPanel/>
时:
<StackPanel>
<ListView>...</ListView>
</StackPanel>
StackPanel
告诉ListView
使用height = infinity渲染其大小。因此,ListView
中的所有2,800个项目实际上都在呈现,而不是虚拟化。
当方向相同时,您必须避免将ListView放在StackPanel中。
这应该有效:
<Grid>
<StackPanel Orientation="Horizontal">
<ListView>...</ListView>
</StackPanel>
</Grid>
......但这太傻了。