WinRT增强了将列表项添加到列表中的性能

时间:2014-07-01 08:59:54

标签: c# listview windows-runtime

当我尝试将一些ObservableCollection项添加到ListView时,我遇到了一个小的性能问题。

这里是ObservableCollection:

    private ObservableCollection<object> children = new ObservableCollection<object>();
    public ObservableCollection<object> Children
    {
        get
        {
            return children;
        }
    }

我还使用了ContentProperty:

[ContentProperty(Name="Children")]

这里是我需要开始添加List的CollectionChanged事件:

void children_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        InitGraphics();
    }  

在InitGraphics()中,我将创建我的List并绘制它所需的所有元素。还有一个名为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 的Usercontrol。每个项目的标准和属性必须相同,并且它们应该是不可更改的。

我需要在其他一些函数中使用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);
        }
    }
}

我在这里遇到的主要问题是,每次收到50个项目时,CollectionChanged事件会被调用50次,而不是一次性接收所有项目。

1 个答案:

答案 0 :(得分:0)

鉴于ItemCollection的文档,我怀疑您需要ReplaceAll方法:

  

对于跟踪“已更改”事件的实现,初始重置会触发一个事件,但添加的项目不会触发离散的每个项目事件。

类似于:

private void SynchronizeList()
{
    // Set properties in each item
    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;
    }
    List.Items.ReplaceAll(children.ToArray());
}

不幸的是,它看起来并不像你真正想要的AddRange ......它至少值得一试。