在UWP Xaml中创建和填充NxN网格

我正在尝试创建一个UWP益智游戏,我想将图片分成n个部分,然后在网格中显示这些部分。

我的问题是,如何强制某种NxN风格。 现在我必须最大化窗口以便看到3×3网格,如果我收缩任何一边,它将收敛到2列,1列网格。 有办法处理这个吗?

这就是我所做的,我知道RowDefinition现在是手动的,直到我找到一个更好的方法来做到这一点。

                       

这是两个示例图像: 想要网格式

不想要gridstyle

可能有几种方法可以做到这一点,这是另一种方法。 我修改了UserControl,以便在页面大小更改和/或集合更改时自动调整项目大小以将其显示为方形网格。

UserControl XAML代码:

                 

UserControl代码背后:

 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:

     

MainPage代码背后:

 public sealed partial class MainPage : Page { private ObservableCollection myItems = new ObservableCollection { 1, 2, 3, 4, 5, 6, 7, 8 }; public ObservableCollection 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); } 

该程序以“Bad Collection”开头 – 有8个项目,因此您无法从它们创建方格,但只要您单击提供的按钮 – 集合的计数将更改为9并且网格应自行更新。

看起来你是通过MVVM这样做的,所以我认为你需要从ViewModel获得你的Rows和Columns的属性。 然后你需要一个转换器来为你的作品提供坐标….或者一个附属物。

这会给你一个想法:

  3 3   // You can bind column and row //            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); } } 

我使用了带有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; 

此代码生成以下输出,如果减小窗口大小,则不会折叠:

3x3矩阵显示

如果这是您想要的,您可以使用以下方法动态添加列。 对于NxN矩阵,您只需要添加N列,绑定将负责rest:

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