Last active
June 23, 2016 21:35
-
-
Save dotMorten/30738245cffb9782cb45ac598fbfaf5e to your computer and use it in GitHub Desktop.
StaggeredGrid
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<ItemsControl x:Name="items" Grid.RowSpan="3" ItemsSource="{x:Bind Data}" Background="LightGray"> | |
<ItemsControl.ItemsPanel> | |
<ItemsPanelTemplate> | |
<local:StaggeredGridPanel /> | |
</ItemsPanelTemplate> | |
</ItemsControl.ItemsPanel> | |
<ItemsControl.ItemTemplate> | |
<DataTemplate> | |
<Border Margin="5" Background="{Binding Brush}" Height="{Binding Height}"> | |
<TextBlock Text="{Binding Name}" HorizontalAlignment="Center" VerticalAlignment="Center" /> | |
</Border> | |
</DataTemplate> | |
</ItemsControl.ItemTemplate> | |
</ItemsControl> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class TestData | |
{ | |
public string Name { get; set; } | |
public SolidColorBrush Brush { get; set; } | |
public double Height { get; set; } | |
} | |
public List<TestData> Data | |
{ | |
get | |
{ | |
Random r = new Random(); | |
var d = new List<TestData>(); | |
for (int i = 0; i < 30; i++) | |
{ | |
d.Add(new TestData() { Name = (i+1).ToString(), Brush = new SolidColorBrush(Windows.UI.Color.FromArgb(255,(byte)(255d/30*i),0, (byte)(255 - (255d / 30 * i)))), Height = r.Next(50, 200) }); | |
} | |
return d; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class StaggeredGridPanel : Panel | |
{ | |
protected override Size ArrangeOverride(Size finalSize) | |
{ | |
int cols = (int)Math.Floor(finalSize.Width / MaxColumnWidth); | |
var w = finalSize.Width / cols; | |
List<double> colHeight = new List<double>(cols); | |
for (int i = 0; i < cols; i++) | |
colHeight.Add(0); | |
foreach (var child in Children) | |
{ | |
//use the shortest column | |
var col = colHeight.IndexOf(colHeight.Min()); | |
double x = w * col; | |
double y = colHeight[col]; | |
child.Arrange(new Rect(x, y, w, child.DesiredSize.Height)); | |
colHeight[col] += child.DesiredSize.Height; | |
} | |
return new Size(finalSize.Width, colHeight.Max()); | |
} | |
protected override Size MeasureOverride(Size availableSize) | |
{ | |
int cols = (int)Math.Floor(availableSize.Width / MaxColumnWidth); | |
var w = availableSize.Width / cols; | |
availableSize = new Size(w, availableSize.Height); | |
List<double> colHeight = new List<double>(cols); | |
for (int i = 0; i < cols; i++) | |
colHeight.Add(0); | |
foreach (var child in Children) | |
{ | |
child.Measure(availableSize); | |
//use the shortest column | |
var col = colHeight.IndexOf(colHeight.Min()); | |
colHeight[col] += child.DesiredSize.Height; | |
} | |
return new Size(availableSize.Width, colHeight.Max()); | |
} | |
public double MaxColumnWidth | |
{ | |
get { return (double)GetValue(MaxColumnWidthProperty); } | |
set { SetValue(MaxColumnWidthProperty, value); } | |
} | |
public static readonly DependencyProperty MaxColumnWidthProperty = | |
DependencyProperty.Register(nameof(MaxColumnWidth), typeof(double), typeof(StaggeredGridPanel), new PropertyMetadata(300d, OnMaxColumnWidthPropertyChanged)); | |
private static void OnMaxColumnWidthPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) | |
{ | |
((StaggeredGridPanel)d).InvalidateMeasure(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment