【问题标题】:Using a custom ListBoxItem definition in ListBox for performance analysis在 ListBox 中使用自定义 ListBoxItem 定义进行性能分析
【发布时间】:2016-06-28 12:01:02
【问题描述】:

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

不幸的是,我无法弄清楚如何在 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);
    }
}

【问题讨论】:

    标签: c# wpf xaml listbox


    【解决方案1】:

    您可以创建一个派生的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;
        }
    }
    

    【讨论】:

    【解决方案2】:

    替换 xaml 中的默认模板:

            <ListBox>
                <ListBox.ItemTemplate>
                    <local:MyListBoxItem />
                </ListBox.ItemTemplate>
            </ListBox>
    

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

    【讨论】:

    • 这会将一个 MyListBoxItem 放入每个 ListBoxItem 的内容中。项目容器仍然是 ListBoxItem。
    • 这对你的目标很重要吗?
    • 当然,问题是关于如何将默认项目容器(即 ListBoxItem)替换为自定义项目容器。
    猜你喜欢
    • 1970-01-01
    • 2010-12-10
    • 1970-01-01
    • 2019-10-10
    • 1970-01-01
    • 1970-01-01
    • 2023-04-10
    • 2023-04-02
    • 1970-01-01
    相关资源
    最近更新 更多