TreeViewItem Virtualization and custom DependencyProperty (C# and WPF)

Viewed 149

Intro

I have a problem with the WPF TreeView control an Virtualization. I guess I reached the possibilities with this control and kinda found out why. Maybe someone can help find the best solution for this.

Problem

I have a custom TreeListView control inherited from TreeView and TreeListViewItem inherited from TreeViewItem. For The TreeListView im using Virtualization. I added a DependencyProperty to TreeListViewItem.

public static readonly DependencyProperty IsItemSelectedProperty = DependencyProperty.Register(
  "IsItemSelected", typeof(bool), typeof(TreeListViewItem), new FrameworkPropertyMetadata(
    false, new PropertyChangedCallback(OnIsItemSelectedChanged)
    )
  ;

public bool IsItemSelected
{
  get { return (bool)GetValue(IsItemSelectedProperty); }
  set { SetValue(IsItemSelectedProperty, value); }
}

With Virtualization active the DP is either (VirtualizationMode = Recycling) wrongly used for new items when scrolling or (VirtualizationMode = Normal) not there anymore.

Cause

TreeView is not saving Properties in Virtualization mode. I digged through the code of TreeViewItem and found the code thats "causing" this.

TreeViewItem.cs line 910 ClearItemContainer function:
https://referencesource.microsoft.com/#PresentationFramework/src/Framework/System/Windows/Controls/TreeViewItem.cs

// Right now we have a hard-coded list of DPs we want to save off.  In the future we could provide a 'register' API
// so that each ItemsControl could decide what DPs to save on its containers. Maybe we define a virtual method to
// retrieve a list of DPs the type is interested in.  Alternatively we could have the contract
// be that ItemsControls use the ItemStorageService inside their ClearContainerForItemOverride by calling into StoreItemValues.

In Helper.cs line 1554:
https://referencesource.microsoft.com/#PresentationFramework/src/Framework/MS/Internal/Helper.cs,de11b95141f7f543

// Since ItemValueStorage is private and only used for TreeView and Grouping virtualization we hardcode the DPs that we'll store in it.
// If we make this available as a service to the rest of the platform we'd come up with some sort of DP registration mechanism.
private static readonly int[] ItemValueStorageIndices = new int[] {
    ItemValueStorageField.GlobalIndex,
    TreeViewItem.IsExpandedProperty.GlobalIndex,
    Expander.IsExpandedProperty.GlobalIndex,
    GroupItem.DesiredPixelItemsSizeCorrectionFactorField.GlobalIndex,
    VirtualizingStackPanel.ItemsHostInsetProperty.GlobalIndex};

So the only Property saved is the IsExpandedProperty. And it's not possible to add own Properties.

What to do?

Is there some other way I'm not seeing to add Properties?
Is there a way to save the Properties on my own?

0 Answers
Related