2015-11-08 8 views
5

Bir UWP puzzle oyunu oluşturmaya çalışıyorum, resmi n parçalara ayırmak ve parçaları bir ızgarada göstermek istiyorum.UWP Xaml'de bir NxN ızgarası oluşturma ve doldurma

Sorunum, belirli bir NxN stilini zorlamaktır. Şu anda 3x3 ızgarayı görmek için pencereyi büyütmek zorundayım, eğer her iki tarafı daraltırsam, 2 sütun, 1 sütun ızgarasına yakınsayacak. Bunu halletmenin bir yolu var mı?

Yaptığım bu, RowDefinition'ın şu anda el ile yapıldığını biliyorum, bunu yapmanın daha iyi bir yolunu bulana kadar.

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

Bu iki örnek görüntülerdir: Wanted gridstyle

Not wanted gridstyle

+0

Bu kodu derleyebildiniz mi? – tgpdyk

+0

evet, aksi takdirde resmi gönderemedim. – fsp

+0

Anladım. .NET 4.5'te, ItemTemplate GridView'ın bir parçası değildir. Neyse, etiketinizi UWP olarak görüyorum, bu yüzden muhtemelen orada çalışıyor. – tgpdyk

cevap

3

burada başka biridir, bunu muhtemelen yollardan çift vardır: NxN matrisinin için, geri kalan ilgilenir bağlayıcı, sadece N sütunları eklemek gerekir. UserControl'u, sayfa boyutu ve/veya koleksiyon değiştiğinde öğeleri kare kare olarak göstermek için otomatik olarak ayarlamasını sağladım.

UserControl XAML kodu:

<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 kod arkasında:

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> 

MainPage kodu arkasında:

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

Program "Bad Collection" ile başlar - 8 öğe vardır, bu yüzden onlardan kare bir kare oluşturamazsınız, ancak sağlanan düğmeyi tıklar tıklamaz - koleksiyonun sayısı 9'a değişir ve ızgara güncellenmelidir kendisi.

0

Eğer MVVM yoluyla yapıyoruz gibi görünüyor, bu yüzden size Satırlar ve Sütunlar için bir mülk olması gerektiğini düşünüyorum ViewModel'inizden. Ve sonra parçalarınız için koordinat sağlamak için bir Dönüştürücü olması gerekir .... VEYA Ekli bir özellik. Görünümde özelliği olduğu gibi

<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

Ben GridView ile bir ListView kullandık:

Bu size bir fikir verecektir. Ve iyi çalışıyor. yapabilirsiniz, bu istediğini ise

3x3 matrix display

:

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

Bu kod çıktısı aşağıda üretir ve pencere boyutunu küçültmek eğer çöktü alamadım Aşağıdaki yaklaşımı kullanarak dinamik olarak sütunlar ekleyin.

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