Create and populate an NxN grid in UWP Xaml

I am trying to create a UWP puzzle game, I want to cut the image into n parts and then show the fragments in the grid.

My problem is how to force a specific NxN style. Right now I have to maximize the window to see a 3x3 grid, if I squeeze it on both sides, it will converge to a grid of 2 columns and 1 column. Is there any way to handle this?

This is what I did, I know that RowDefinition now works manually until I find a better way to do this.

<UserControl x:Class="PictureSplitter.Views.PictureView" 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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="400"> <GridView ItemsSource="{Binding Splitter.PuzzlePositions}"> <GridView.ItemTemplate> <DataTemplate> <Border BorderBrush="Red" BorderThickness="2"> <Grid x:Name="picGrid"> <Grid.RowDefinitions> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> <RowDefinition Height="Auto"></RowDefinition> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> <ColumnDefinition Width="Auto"></ColumnDefinition> </Grid.ColumnDefinitions> <Image Source="{Binding Piece.ImageSource}" /> </Grid> </Border> </DataTemplate> </GridView.ItemTemplate> </GridView> </UserControl> 

These are two example images: Gridstyle required

No gridstyle required

+5
source share
3 answers

There are probably several ways to do this, here is another one. I changed the UserControl so that it automatically adjusts the size of the elements to show them as a square grid when the page resizes and / or the collection changes.

UserControl XAML Code:

 <UserControl x:Class="MyControls.MyUserControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:MyControls" Name="myControl"> <GridView Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" ItemsSource="{Binding ElementName=myControl, Path=Items}" Width="{Binding ElementName=myControl, Path=CurrentWidth}" HorizontalAlignment="Center" Height="{Binding Width, RelativeSource={RelativeSource Self}}"> <GridView.ItemContainerStyle> <Style TargetType="GridViewItem"> <Setter Property="Margin" Value="0"/> </Style> </GridView.ItemContainerStyle> <GridView.ItemTemplate> <DataTemplate> <Border Padding="10" Width="{Binding ElementName=myControl, Path=ElementSize}" Height="{Binding ElementName=Width, RelativeSource={RelativeSource Self}}"> <Border BorderBrush="Red" BorderThickness="3"> <Image Source="ms-appx:///Assets/StoreLogo.png" Stretch="UniformToFill"/> </Border> </Border> </DataTemplate> </GridView.ItemTemplate> </GridView> </UserControl> 

UserControl code behind:

 public sealed partial class MyUserControl : UserControl, INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; private void RaiseProperty(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name)); public IList Items { get { return (IList)GetValue(ItemsProperty); } set { SetValue(ItemsProperty, value); } } public static readonly DependencyProperty ItemsProperty = DependencyProperty.Register("Items", typeof(IList), typeof(MyUserControl), new PropertyMetadata(0, (s, e) => { if (Math.Sqrt((e.NewValue as IList).Count) % 1 != 0) Debug.WriteLine("Bad Collection"); })); public void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) { if (Math.Sqrt(Items.Count) % 1 != 0) Debug.WriteLine("Bad Collection"); RaiseProperty(nameof(ElementSize)); } private double currentWidth; public double CurrentWidth { get { return currentWidth; } set { currentWidth = value; RaiseProperty(nameof(CurrentWidth)); RaiseProperty(nameof(ElementSize)); } } public double ElementSize => (int)(currentWidth / (int)Math.Sqrt(Items.Count)) - 1; public MyUserControl() { this.InitializeComponent(); } } 

MainPage XAML:

 <Grid> <local:MyUserControl x:Name="myControl" Items="{Binding MyItems}"/> <Button Content="Add" Click="Button_Click"/> </Grid> 

Homepage Code:

 public sealed partial class MainPage : Page { private ObservableCollection<int> myItems = new ObservableCollection<int> { 1, 2, 3, 4, 5, 6, 7, 8 }; public ObservableCollection<int> MyItems { get { return myItems; } set { myItems = value; } } public MainPage() { this.InitializeComponent(); DataContext = this; MyItems.CollectionChanged += myControl.Items_CollectionChanged; } protected override Size MeasureOverride(Size availableSize) { myControl.CurrentWidth = Math.Min(availableSize.Height, availableSize.Width); return base.MeasureOverride(availableSize); } private void Button_Click(object sender, RoutedEventArgs e) => MyItems.Add(3); } 

The program starts with "Bad Collection" - there are 8 elements, so you cannot make a square grid out of them, but as soon as you click on the provided button, the collection count will change to 9 and the grid should update by itself.

+3
source

It looks like you are doing this using MVVM, so I think you need to have a property for the rows and columns from the ViewModel. And then you should have a converter to supply coordinates for your parts .... OR Attached property.

This will give you an idea:

 <Window.Resources> <System:Int64 x:Key="X">3</System:Int64> <System:Int64 x:Key="Y">3</System:Int64> </Window.Resources> <Grid x:Name="myGrid" Loaded="Grid_Loaded"> // You can bind column and row // <Button Content="image1" Grid.Column="{Binding column}" Grid.Row="{Binding row}"/> <Button Content="image1" Grid.Column="0" Grid.Row="0"/> <Button Content="image2" Grid.Column="1" Grid.Row="0"/> <Button Content="image3" Grid.Column="2" Grid.Row="0"/> <Button Content="image4" Grid.Column="0" Grid.Row="1"/> <Button Content="image5" Grid.Column="1" Grid.Row="1"/> <Button Content="image6" Grid.Column="2" Grid.Row="1"/> <Button Content="image7" Grid.Column="0" Grid.Row="2"/> <Button Content="image8" Grid.Column="1" Grid.Row="2"/> <Button Content="image9" Grid.Column="2" Grid.Row="2"/> </Grid> private void Grid_Loaded(object sender, RoutedEventArgs e) { Int64 X = (Int64) this.FindResource("X"); Int64 Y = (Int64) this.FindResource("Y"); for (Int64 i = 0; i < X; i++) { ColumnDefinition c = new ColumnDefinition(); myGrid.ColumnDefinitions.Add(c); } for (Int64 i = 0; i < (int)Y; i++) { RowDefinition r = new RowDefinition(); myGrid.RowDefinitions.Add(r); } } 
0
source

I used a ListView with a GridView as a View property. And it works fine.

 <ListView x:Name="ImageList" Width="210" Height="210"> <ListView.View> <GridView> <GridView.ColumnHeaderContainerStyle> <Style TargetType="Control"> <Setter Property="Visibility" Value="Collapsed"/> </Style> </GridView.ColumnHeaderContainerStyle> <GridViewColumn> <GridViewColumn.CellTemplate> <DataTemplate> <Image Source="{Binding sq1}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn > <GridViewColumn.CellTemplate> <DataTemplate> <Image Source="{Binding sq2}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> <GridViewColumn > <GridViewColumn.CellTemplate> <DataTemplate> <Image Source="{Binding sq3}"/> </DataTemplate> </GridViewColumn.CellTemplate> </GridViewColumn> </GridView> </ListView.View> 

 var imgBox = new BitmapImage(new Uri(@"/images/cellbkg.jpg", UriKind.Relative)); var source = new[] { new { sq1 = imgBox, sq2 = imgBox, sq3 = imgBox }, new { sq1 = imgBox, sq2 = imgBox, sq3 = imgBox }, new { sq1 = imgBox, sq2 = imgBox, sq3 = imgBox } }; ImageList.ItemsSource = source; 

This code displays the result below and does not collapse if you reduce the window size:

3x3 dot matrix display

If this is what you want, you can dynamically add columns using the approach below. For the NxN matrix, you need to add only N columns, the binding will take care of the rest:

  GridView view = (GridView)ImageList.View; view.Columns.Add(new GridViewColumn()); 
0
source

Source: https://habr.com/ru/post/1235442/


All Articles