Here is a prototype that you can use to experiment with various options:
<Grid>
<Grid.Resources>
<local:Range x:Key="sampleData" Minimum="1" Maximum="900"/>
</Grid.Resources>
<ItemsControl ItemsSource="{StaticResource sampleData}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<UniformGrid Rows="30" Columns="30"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" FontSize="8">
<TextBlock.LayoutTransform>
<RotateTransform Angle="30"/>
</TextBlock.LayoutTransform>
</TextBlock>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
and data generator:
class Range : List<int>, ISupportInitialize
{
public int Minimum { get; set; }
public int Maximum { get; set; }
public void BeginInit() { }
public void EndInit()
{
for (int i = Minimum; i <= Maximum; i++) Add(i);
}
}
and the upper left corner is as follows:

You can call up the layout by resizing the window, and on my machine it is a little sluggish, but applicable. Then you can test other containers, other transformations, layout and rendering conversions, etc., to find out what they are doing.
source
share