2015-11-08 70 views
5

我想創建一個UWP益智遊戲,我想將圖片剪切成n個部分,然後在網格中顯示這些部分。在UWP中創建和填充NxN網格Xaml

我的問題是,如何強制某種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> 

這兩個示例圖像: 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的MainPage:

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

代碼的MainPage背後:

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

該程序以「壞集合」開頭 - 有8個項目,因此您無法從中創建方形網格,但只要您單擊提供的按鈕 - 集合的計數將更改爲9,網格應該更新本身。

0

它看起來像你被MVVM的方式這樣做,所以我覺得你需要爲你的行和列的屬性從你的ViewModel。然後你需要有一個轉換器來爲你的作品提供座標......或者一個附屬屬性。

這會給你一個想法:

<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,因爲它是View屬性。它工作正常。

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

這段代碼產生下面的輸出,如果你減少窗口大小沒有得到崩潰:

3x3 matrix display

如果這是你想要什麼,你可以使用下面的方法動態添加列。對於N×N的矩陣,你必須只添加N列,綁定將剩下的工作:

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