1

I want to make a simple board game for windows phone that has 5 x 5 square shaped tiles on it. Obviously I'd like it to have a dynamic interface where the tiles' width and height property are set according to the user's phone resolution. For that matter, in my XAML code I have used the * thing to divide my page width into 5 columns(relative size) and in each column I have a stack panel to which I add 5 buttons. like this:

    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
            <ColumnDefinition Width="1*"/>
        </Grid.ColumnDefinitions>
        <StackPanel x:Name="ButtonsCol0" Grid.Column="0">
            <Button Background="AliceBlue"
               MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
               MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
            </Button>
            <Button 
               MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
               MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
            </Button>
            <Button 
               MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
               MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
            </Button>
            <Button 
               MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
               MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
            </Button>
            <Button 
               MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
               MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">
            </Button>
        </StackPanel>

(I have 4 more of the StackPanel above for each column)

Now the problem is that I want the tiles to have a square shape(same height and width), I found this question and that is why I added:

    MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
    MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}">

to my buttons, this seems to work but when I run the code, the result is like this:

enter image description here

please help... :)

Community
  • 1
  • 1
Reza Shayestehpour
  • 1,693
  • 3
  • 19
  • 27
  • Stackpanels automatically shrink to only use the amount of space required by the children within them - for full screen layouts use `` (grid automatically fills the parent container by default). It's a bit more XAML to set it up, but it ensures you have a stretched or specified height/width layout and the content automatically scales. You can remove any size settings on the buttons if you use a grid - the buttons can autosize within the grid cells. – Charleh Nov 15 '13 at 11:25

2 Answers2

1

You could do something a bit differemt, like this (just an idea) :

Make a grid that would contain your buttons.

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>
    <!-- If you add the buttons in the Grid's cells, -->
    <!-- they should expand to the available width and height -->

    <Button Grid.Row="0" Grid.Column="0"
        MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
        MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"/>
    <Button Grid.Row="0" Grid.Column="1"
        MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
        MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"/>

     .... 23 more buttons
</Grid>

Also, (I never used this), take a look at these (inversed) bindings :

MinWidth="{Binding ActualHeight, RelativeSource={RelativeSource Self}}" 
MinHeight="{Binding ActualWidth, RelativeSource={RelativeSource Self}}"

This means MinWidth and MinHeight would still not match - try using the same value : Store initial value ActualWidth to a property, and then bind that property to both MinWidth and MinHeight :

MinWidth="{Binding FixedSize, RelativeSource={RelativeSource Self}}" 
MinHeight="{Binding FixedSize, RelativeSource={RelativeSource Self}}"

where FixedSize is the propery that contains the initial ActualWidth

This should be fine but as soon as you change orientation, I think it will all be messed up. It depends if you want your app to have locked orientation, or should adapt. If it should adapt, binding should change as well.

But I guess it's still cumbersome... you'd better have a matrix (2D array of buttons) and add them to the View - cause in this way you will be able to manage them easier by simply accessing them from the array instead of accessing them like : ButtonCol0Row0, ButtonCol0Row1 etc...

VasileF
  • 2,856
  • 2
  • 23
  • 36
  • Don't bother setting the button sizes... they will automatically scale within the grid cells - it's pointless unless you need them to do something other than stretch - and making them diff sizes can easily be done using the `Margin` property on each button. – Charleh Nov 15 '13 at 11:27
  • @Vasile Marian Fălămaș,first thanks for your time, as I said to @charleh, this code makes 25 grid cells that are dynamically sized according to the screen resolution, but which are not necessarily square shaped(width - height). So somehow I should do something about the sizes, and the problem with the `MinHeight` and `MinWidth` bindings above is that when one of them(height in portrait orientation) is bigger than the cell size , that makes the other one (width) go out of the grid too... – Reza Shayestehpour Nov 15 '13 at 12:50
  • By the way I don't know why, but these binding seem to work when I'm writing my `XAML` code, and they reflect through the designer pane, but when I run the code, they don't work at all... – Reza Shayestehpour Nov 15 '13 at 12:59
1

Definitely use a grid. This will give you a uniform grid which fills the parent container. You can set margins on the buttons or the grid as appropriate. Note that the default HorizontalAlignment and VerticalAlignment for controls is "Stretch" so you don't need to set any sizes on the buttons!

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="*" />
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <Button Grid.Row="0" Grid.Column="0" />
    <Button Grid.Row="0" Grid.Column="1" />
    ... etc
</Grid>

If you want to get hold of the buttons as another poster has said, you can add them to an array instead of defining them in XAML - or you could just loop through grid children since they will be declared in the order specified (make sure you specify them in the correct order from left/right/top/bottom) and you can add the buttons created in the XAML to an array instead. Your call (I don't like creating controls in code - I think you should be as declarative as possible in your XAML)

Charleh
  • 13,749
  • 3
  • 37
  • 57
  • dear @charleh first of all thanks for your time, but this code makes 25 grid cells that are dynamically sized according to the screen resolution, but which are not necessarily square shaped(width - height). And since as you mentioned the buttons stretch to fill the cell, in result they are shaped as rectangles. – Reza Shayestehpour Nov 15 '13 at 12:35
  • Just set the size/width to be 1:1 aspect ratio by detecting the actual size and cropping the bigger dimension to the size of the smaller dimension. You still don't need to set the sizes of the buttons as the grid will be square therefore the buttons will also be square – Charleh Nov 15 '13 at 13:33
  • I'm new to windows phone developing and xaml, I would really appreciate it if you could tell me specifically how to do that... :) thanks a lot.. – Reza Shayestehpour Nov 15 '13 at 13:40
  • You can write a method so that when the view loads (OnLoaded will probably work fine) it looks at the ActualWidth and ActualHeight of the grid (if you name your grid with `x:Name="SomeGrid"` in XAML you can reference it in the code-behind). If one is greater than the other, set the greater one to the value of the smaller one (you might have to set Width and not ActualWidth) and it should work fine. – Charleh Nov 15 '13 at 15:14
  • e.g. If `var max = Math.Max(SomeGrid.ActualHeight, SomeGrid.ActualWidth);` then `SomeGrid.Width = SomeGrid.Height = max;` – Charleh Nov 15 '13 at 15:19