Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UWP: Alternative to Grid.IsSharedSizeScope and SharedSizeGroup

Tags:

c#

wpf

uwp

I got the same issue as described in the following, old, forum post: Issue on MSDN
However, for some reason Microsoft decided to remove the functionalities in the answer described there.

What I'm looking for is a ListView with 2+ columns, with the first column containing random data (thus random width elements), making the width of the first column the same as the widest element inside.

like image 212
ManIkWeet Avatar asked Feb 07 '16 15:02

ManIkWeet


1 Answers

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.

enter image description here

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.

like image 90
Margus Avatar answered Oct 12 '22 19:10

Margus