Reputation: 1703
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:
please help... :)
Upvotes: 1
Views: 1601
Reputation: 14012
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)
Upvotes: 1
Reputation: 2916
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...
Upvotes: 1