2016-06-28 84 views
1

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

不幸的是我不知道如何在ListBox内使用这个类。我想在这样的Items="{Binding Path=ListBoxItemsList}" XAML MyListBoxItem实例列表结合ListBox.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); 
    } 
} 

回答

3

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

这很好。谢谢!有关详细信息,我后来发现此链接:http://drwpf.com/blog/2008/07/20/itemscontrol-g-is-for-generator/ – packoman

0

替换xaml中的deafult模板:

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

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

+0

这会将MyListBoxItem放入每个ListBoxItem的内容中。该项目容器仍然是一个ListBoxItem。 – Clemens

+0

这对你的目标很重要吗? – Arheus

+0

当然,问题是如何*自定义一个*替换默认项目容器(即ListBoxItem)。 – Clemens