namespace Common.UI.Controls { using Common.UI.ViewModels; using System.Collections.Generic; using System.Linq; using System.Windows; using System.Windows.Controls; public partial class GridLayout : Grid { public static readonly DependencyProperty ItemsSourceProperty = DependencyProperty.Register( name: nameof(ItemsSource) , propertyType: typeof(IEnumerable) , ownerType: typeof(GridLayout) , typeMetadata: new FrameworkPropertyMetadata(null, ItemsSourceChanged)); public GridLayout() => this.InitializeComponent(); public IEnumerable ItemsSource { get => this.GetValue(ItemsSourceProperty) as IEnumerable; set => this.SetValue(ItemsSourceProperty, value); } private void UpdateItemsCollection() { if (this.ItemsSource?.Count() <= 0) { return; } this.Children.Clear(); this.RowDefinitions.Clear(); this.ColumnDefinitions.Clear(); var rowsCount = this.ItemsSource.Max(x => x.Row) + 1; for (var i = 0; i < rowsCount; i++) { this.RowDefinitions.Add(new RowDefinition { Height = GridLength.Auto }); } var columnsCount = this.ItemsSource.Max(x => x.Column) + 1; for (var i = 0; i < columnsCount; i++) { this.ColumnDefinitions.Add(new ColumnDefinition { Width = new GridLength(1, GridUnitType.Star)/*, MinWidth = 200*/ }); } foreach (var item in this.ItemsSource) { var content = new ContentControl { Content = item }; SetRow(content, item.Row); SetRowSpan(content, item.RowSpan); SetColumn(content, item.Column); SetColumnSpan(content, item.ColumnSpan); this.Children.Add(content); } } private static void ItemsSourceChanged(DependencyObject control, DependencyPropertyChangedEventArgs args) { if (control is GridLayout gridLayout) { gridLayout.Dispatcher.Invoke(gridLayout.UpdateItemsCollection); } } } }