Reputation: 5744
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 ItemsControl
s (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 VirtualizingStackPanel
s in the above tree have a vertical/default orientation, and horizontal arrangement for the last layer comes from Expander
s.
Here's what the above looks like. "ALPHA" is a TopLevelItem
, the Guids are MidLevelItem
s, and each hex pair is an individual LowLevelItem
(which you'll notice are not wrapping but continue past the edge):
Upvotes: 3
Views: 489
Reputation: 169200
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
.
Upvotes: 1