The SharedSizeGroup
is a exclusive to WPF and does not exist in UWP.
Goal : create alternative to SharedSizeGroup
In order to know the measure, we need to look at all of the controls and find the maximum.
What we will be making
We use Fody and PropertyChanged.Fody nuget packages. While they are not required for read-only example, it's useful if you start to modifying the data. I add SizeChanged
event handler and modify the width directly. You can set a property and bind to instead or create a behavior, but this is how it is done.
View
<Page
x:Class="TestUwp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="using:TestUwp"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
d:DataContext="{d:DesignInstance Type=local:DataItem}"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
mc:Ignorable="d">
<ListView ItemsSource="{Binding TestData}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel>
<Grid ColumnSpacing="6" RowSpacing="6">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBlock
Grid.Column="0"
SizeChanged="LabelSizeChanged"
Text="{Binding FirstName}" />
<TextBlock Grid.Column="1" Text="{Binding LastName}" />
</Grid>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Page>
Model and ViewModel
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace TestUwp
{
public class DataItem : INotifyPropertyChanged
{
public DataItem(int id, string firstName, string lastName)
{
Id = id;
FirstName = firstName;
LastName = lastName;
}
public int Id { get; set; }
public string FirstName { get; set; }
public string LastName { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
}
public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();
TestData = new ObservableCollection<DataItem> {
new DataItem(1, "Pauly", "Thurlborn"),
new DataItem(2, "Orbadiah", "Ewen"),
new DataItem(3, "Britni" ,"Smead"),
new DataItem(4, "Fionna" ,"Jennemann"),
new DataItem(5, "Ashley" ,"Stoddart"),
new DataItem(6, "Bradford", "Kaesmakers"),
new DataItem(7, "Maxy" ,"Lemon"),
new DataItem(8, "Rasia" ,"Comber"),
new DataItem(9, "Colas" ,"Shepton"),
new DataItem(10, "Cacilie" ,"Tummons"),
};
DataContext = this;
}
public ObservableCollection<DataItem> TestData { get; set; }
private List<ColumnDefinition> _columns = new List<ColumnDefinition>();
private double _colSize = 0.0;
private void LabelSizeChanged(object sender, SizeChangedEventArgs e)
{
var item = (dynamic)sender;
var grid = (Grid)item.Parent;
var column = grid.ColumnDefinitions[0];
if (!_columns.Contains(column))
{
_columns.Add(column);
}
var adjustments = new List<ColumnDefinition>();
if (item.ActualWidth > _colSize)
{
_colSize = item.ActualWidth;
adjustments.AddRange(_columns);
}
else
{
adjustments.Add(column);
}
foreach (var col in adjustments)
{
col.Width = new GridLength(_colSize);
}
}
}
}
The source of this idea originates in Xamarin.