在ListBox中使用自定义ListBoxItem定义进行性能分析

本文关键字:性能 定义 ListBoxItem ListBox 自定义 | 更新日期: 2023-09-27 17:52:51

我试图分析我的代码的性能,并更好地理解WPF的画布的重绘行为,我使用作为ListBox内的ItemsPanel。为此,我定义了一个自定义类MyListBoxItem,它派生自ListBoxItem(见下面的代码)。

不幸的是,我不知道如何在ListBox中使用这个类。我尝试将MyListBoxItem实例列表绑定到XAML中的ListBox.Items,如Items="{Binding Path=ListBoxItemsList}",但随后我得到错误

'Items'属性是只读的,不能从标记设置。

有办法做到这一点吗?或者也许有其他方法可以实现我正在做的事情?(即对重绘行为的分析)

MyListBoxItem: 定义
public class MyListBoxItem : ListBoxItem
{
    public MyListBoxItem(ObjectViewModel vm)
    {
        this.DataContext = vm;
    }
    Size? arrangeResult;
    protected override Size MeasureOverride(Size constraint)
    {
        var vm = (this.DataContext as ObjectViewModel);
        if (vm != null)
        {
            Debug.WriteLine("For ObjectViewModel " + vm.Name + ":");
        }
        arrangeResult = null;
        System.Console.WriteLine("MeasureOverride called for " + this.Name + ".");
        return base.MeasureOverride(constraint);
    }
    protected override System.Windows.Size ArrangeOverride(System.Windows.Size arrangeSize)
    {
        if (!arrangeResult.HasValue)
        {
            System.Console.WriteLine("ArrangeOverride called for " + this.Name + ".");
            // Do your arrange work here
            arrangeResult = base.ArrangeOverride(arrangeSize);
        }
        return arrangeResult.Value;
    }
    protected override void OnRender(System.Windows.Media.DrawingContext dc)
    {
        System.Console.WriteLine("OnRender called for " + this.Name + ".");
        base.OnRender(dc);
    }
}

在ListBox中使用自定义ListBoxItem定义进行性能分析

您可以创建一个派生的ListBox,它覆盖GetContainerForItemOverrideIsItemItsOwnContainerOverride方法来返回一个自定义的ListBoxItem:

public class MyListBoxItem : ListBoxItem
{
}
public class MyListBox : ListBox
{
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new MyListBoxItem();
    }
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return item is MyListBoxItem;
    }
}

在xaml:

中替换deafult模板
        <ListBox>
            <ListBox.ItemTemplate>
                <local:MyListBoxItem />
            </ListBox.ItemTemplate>
        </ListBox>

并从渲染中删除日志。我认为这会产生太多的垃圾邮件。