2015-11-08 16 views
5

Tôi đang cố gắng tạo một trò chơi câu đố UWP, tôi muốn cắt ảnh thành các phần n rồi hiển thị các phần trong lưới.Tạo và điền vào lưới NxN trong UWP Xaml

Vấn đề của tôi là, cách buộc một kiểu NxN nhất định. Ngay bây giờ tôi phải phóng to cửa sổ để thấy một lưới 3x3, nếu tôi thu nhỏ hai bên, nó sẽ hội tụ thành một cột 2 cột, 1 cột. Có cách nào để xử lý việc này không?

Đây là những gì tôi đã làm, tôi biết RowDefinition là thủ công ngay bây giờ, cho đến khi tôi tìm ra cách tốt hơn để làm điều đó.

<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> 

Đây là hai ví dụ hình ảnh: Wanted gridstyle

Not wanted gridstyle

+0

Bạn có thể biên dịch mã này không? – tgpdyk

+0

có, nếu không tôi sẽ không thể đăng ảnh. – fsp

+0

Tôi hiểu. Trong .NET 4.5, ItemTemplate không phải là một phần của GridView. Dù sao, tôi thấy thẻ của bạn là UWP nên có lẽ nó đang hoạt động ở đó. – tgpdyk

Trả lời

3

Có thể có vài cách để làm điều đó, đây là một cách khác. Tôi đã sửa đổi UserControl để nó tự động điều chỉnh kích thước mục để hiển thị chúng dưới dạng lưới vuông, khi thay đổi kích thước trang và/hoặc thay đổi bộ sưu tập.

Mã UserControl XAML:

<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> 

đang UserControl đằng sau:

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(); 
    } 
} 

Các Mainpage XAML:

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

đang Mainpage đằng sau:

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); 
} 

Chương trình bắt đầu bằng "Bộ sưu tập xấu" - có 8 mục, vì vậy bạn không thể tạo lưới vuông từ chúng, nhưng ngay khi bạn nhấp vào nút được cung cấp - số lượng bộ sưu tập thay đổi thành 9 và lưới sẽ cập nhật chinh no.

0

Dường như bạn đang làm điều này bằng cách MVVM, vì vậy tôi nghĩ rằng bạn cần phải có một tài sản cho dòng và cột của bạn từ ViewModel của bạn. Và sau đó bạn cần phải có một Converter để cung cấp tọa độ cho các mảnh của bạn .... HOẶC một tài sản đính kèm.

này sẽ cung cấp cho bạn một ý tưởng:

<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

Tôi đã sử dụng một ListView với GridView như nó Xem tài sản. Và nó hoạt động tốt.

<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; 

Mã này tạo ra bên dưới đầu ra, và không bị sụp đổ nếu bạn giảm kích thước cửa sổ:

3x3 matrix display

Nếu đây là những gì bạn muốn, bạn có thể thêm cột động bằng cách sử dụng phương pháp tiếp cận bên dưới. Đối với ma trận NxN, bạn phải thêm chỉ N cột, ràng buộc sẽ đảm bảo phần còn lại:

 GridView view = (GridView)ImageList.View; 
     view.Columns.Add(new GridViewColumn()); 
Các vấn đề liên quan