【发布时间】:2014-07-01 08:59:54
【问题描述】:
我在尝试将 ObservableCollection 的一些项添加到 ListView 时遇到了一个小性能问题。
这是 ObservableCollection:
private ObservableCollection<object> children = new ObservableCollection<object>();
public ObservableCollection<object> Children
{
get
{
return children;
}
}
我也在使用 ContentProperty:
[ContentProperty(Name="Children")]
这是我需要开始添加列表的 CollectionChanged 事件:
void children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
InitGraphics();
}
在 InitGraphics() 中,我将创建我的列表并绘制它所需的所有元素。还有一个名为 SynchronizeList() 的函数,它在 InitGraphics() 的开头被调用。
SynchronizeList() 看起来像这样:
private void SynchronizeList()
{
foreach (var item in children)
{
//Casting ListViewItem as ValueBoxControl
ValueBoxControl control = (ValueBoxControl)item;
//Standards and needed attributes
control.ValueTextBox.IsHitTestVisible = false;
control.ClipColor = ClipColor;
control.Foreground = this.Foreground;
//Add the Item to the List
List.Items.Add(item);
}
}
现在,如您所见,我的 ListView 称为 List,而 Items 是称为 ValueBoxControl 的用户控件。每个项目的标准和属性必须相同,并且不能更改。
我需要在其他几个函数中使用 SynchronizeList() 函数(例如:当 List 被切换两次时,我删除所有 Items 并使用 SynchronizeList() 再次添加它们等)。
当我添加大约 50 多个项目时会出现问题,因为它显然必须通过 foreach 循环运行 50 次并添加每个项目。在调试时,我注意到子集合从一开始就没有全部 50 个项目。它首先有 1 个项目,然后是 2 个,然后是 3 个,以此类推。 这意味着 SynchronizeList() 被调用了 50 次,首先添加 1 个项目,然后是 2,然后是 3,等等。
我已经尝试了很多事情(例如在 CollectionChangedEvent 中使用 e.NewItems),但目前我认为没有可能的解决方案。
这是我的片段中的一个完整示例,它显示了我的问题:
//ContentProperty to receive Items from XAML with the help of an ObservableCollection
[ContentProperty(Name="Children")]
public sealed partial class ListViewControl : ValueBoxControl
{
//Create a new ListView
ListView List = new ListView();
//Initialization
public ListViewControl()
{
//Events
children.CollectionChanged += children_CollectionChanged;
}
//ObservableCollection to receive Items from XAML
private ObservableCollection<object> children = new ObservableCollection<object>();
public ObservableCollection<object> Children
{
get
{
return children;
}
}
//Event which gets called whenever the List in XAML gets changed
void children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
{
//Calls the function to draw the List
InitGraphics();
}
private void InitGraphics()
{
SynchronizeList();
if (List.Items.Counter >= 1)
{
//Draw the ListView with a custom design
}
}
private void SynchronizeList()
{
//Get each item in the ObservableCollection and add some attributes
foreach (var item in children)
{
//ListViewItem casted as ValueBoxControl
ValueBoxControl control = (ValueBoxControl)item;
//Standards & Limitations
control.ValueTextBox.IsHitTestVisible = false;
control.ClipColor = ClipColor;
control.Foreground = this.Foreground;
//Add Item to ListView
List.Items.Add(item);
}
}
}
我在这里遇到的主要问题是 CollectionChanged 事件被调用了 50 次 50 个项目,每次接收一个新项目,而不是一次性接收所有项目。
【问题讨论】:
-
我对
List属性是什么感到困惑 - 那是ObservableCollection吗? -
@JonSkeet 我已经在最后一个代码sn-p之后的第一句话中写了。这是一个简单的 ListView:
ListView List = new ListView(); -
啊,对。你的代码很难理解,因为它是零散的,而且你有一些需要额外描述的部分。一个简短但完整的示例会更容易理解...
-
嗯,我使用这些函数的整个 ListControl 有 600 行代码,所以我提取了这些函数以保持简短。如果您认为它有优势,我仍然可以发布整个代码。但简而言之,我的问题是 CollectionChanged 事件为 50 个项目被调用 50 次,而不是为所有 50 个项目调用一次。
-
我并没有说我想要你的全部实际代码。我想要一个简短但完整的示例来演示问题,并且什么都不做。不过,您可能想查看
ReplaceAll方法。
标签: c# listview windows-runtime