Inside a Page I have the below TreeView. How can I get the things inside the ItemsControl to wrap instead of scrolling off the edge of the page? The WrapPanel doesn't seem to be doing anything.
Note this is not the same as asking how to wrap leaf items--I don't need to wrap ItemsControls (there's only one), but need to wrap the things inside the ItemsControl.
<TreeView
VirtualizingPanel.IsVirtualizing="True"
VirtualizingPanel.VirtualizationMode="Recycling"
VirtualizingPanel.ScrollUnit="Pixel"
VirtualizingPanel.IsVirtualizingWhenGrouping="True"
Name="Tree">
<TreeView.ItemTemplate>
<HierarchicalDataTemplate
DataType="{x:Type viewModel:HighLevelItem}"
ItemsSource="{Binding MidLevelItems}">
<TextBlock
Text="{Binding HighLevelName}"/>
<HierarchicalDataTemplate.ItemTemplate>
<DataTemplate
DataType="{x:Type viewModel:MidLevelItem}">
<Expander>
<Expander.Header>
<TextBlock
Text="{Binding MidLevelName}"/>
</Expander.Header>
<Expander.Content>
<ItemsControl
ItemsSource="{Binding LowLevelItems}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel
Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock
Text="{Binding LowLevelName}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Expander.Content>
</Expander>
</DataTemplate>
</HierarchicalDataTemplate.ItemTemplate>
</HierarchicalDataTemplate>
</TreeView.ItemTemplate>
</TreeView>
...here are some type definitions:
public class HighLevelItem
{
public MidLevelItem[] MidLevelItems { get; set; }
public string HighLevelName { get; set; }
}
public class MidLevelItem
{
public LowLevelItem[] LowLevelItems { get; set; }
public string MidLevelName { get; set; }
}
public class LowLevelItem
{
public string LowLevelName { get; set; }
}
...and somewhere else in your code (to get the TreeView to populate):
Tree.Items = new[] { new HighLevelItem { HighLevelName = "ALPHA", MidLevelItems = Enumerable.Repeat(0, 1000).Select(_ => new MidLevelItem { MidLevelName = Guid.NewGuid().ToString(), LowLevelItems = Enumerable.Repeat(0, 1000).Select(__ => new LowLevelItem { LowLevelName = "ff" }).ToArray() }).ToArray() } };
Also note that I'm using an Expander instead of continuing with another hierarchical data template because I need that layer to have items arranged horizontally, and changing the Orientation of the VirtualizingStackPanel at any layer within the tree to be different than the other layers breaks UI virtualization for the entire tree when that layer is expanded. Hence all the VirtualizingStackPanels in the above tree have a vertical/default orientation, and horizontal arrangement for the last layer comes from Expanders.
Here's what the above looks like. "ALPHA" is a TopLevelItem, the Guids are MidLevelItems, and each hex pair is an individual LowLevelItem (which you'll notice are not wrapping but continue past the edge):

You need to specify the Width of the Expander, e.g.:
<Expander Width="{Binding ActualWidth, RelativeSource={RelativeSource AncestorType=TreeView}}">
...
You may want to use a converter or something that subtracts the offset from the left edge side from the ActualWidth of the TreeView.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With