2015-11-08 22 views
5

UWPパズルゲームを作成しようとしていますが、画像をn個に分割してグリッドに表示する必要があります。UWP XamlでNxNグリッドを作成して塗りつぶし

私の問題は、特定のNxNスタイルを強制する方法です。今私は3x3のグリッドを見るためにウィンドウを最大化する必要があります、私はどちらかの側を縮小する場合、それは2列、1列のグリッドに収束します。これを処理する方法はありますか?

これは私がやったことです、私はそれを行うためのより良い方法を見つけるまで、RowDefinitionは現在手動であることを知っています。

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

これは、2つのサンプル画像です: Wanted gridstyle

Not wanted gridstyle

+0

このコードをコンパイルできましたか? – tgpdyk

+0

はい、それ以外の場合は画像を投稿できません。 – fsp

+0

私は参照してください。 .NET 4.5では、ItemTemplateはGridViewの一部ではありません。とにかく、私はあなたのタグをUWPと見なしているので、おそらくそこで働いています。 – tgpdyk

答えて

3

はそれを行うにはいくつかの方法は、おそらくありますが、ここでは別のものです。私は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> 

後ろユーザーコントロールコード:

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

メインページのXAML:後ろ

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

メインページコード:

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

プログラムは「Bad Collection」で始まります.8つのアイテムがありますので正方形のグリッドを作ることはできませんが、ボタンをクリックするとすぐにコレクションの数は9に変わり、グリッドが更新されます自体。

0

あなたはMVVMの方法でこれをやっているように見えたので、私はあなたの行と列のプロパティを持っている必要があると思いますあなたのViewModelから。そしてあなたはあなたの作品の座標を供給するためにコンバータを持っている必要があります....またはAttachedプロパティ。それはViewプロパティだとして

<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

私はGridViewコントロールとListViewコントロールを使用しています

これはあなたのアイデアを与えるだろう。そして、それは正常に動作しています。することができます、これはあなたが望むものである場合

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; 

このコードは、出力の下に生成し、そしてあなたは、ウィンドウのサイズを小さくする場合は崩れません。以下のアプローチを使用して動的に列を追加します。 N×N個の行列について、あなたは残りの世話をする結合、唯一のN列を追加する必要があります。

 GridView view = (GridView)ImageList.View; 
     view.Columns.Add(new GridViewColumn()); 
関連する問題