Currently I am struggling to get a control to be displayed in a box shape in WPF without having to need to result to code. Here is a working example of what I want it to look like:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="3" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<Button Margin="6" VerticalAlignment="Stretch" Width="{Binding Path=ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="http://blog.joeclarmusic.com/images/rss-icon.jpg" />
<TextBlock Foreground="Black" TextAlignment="Center" Grid.Row="1" FontSize="11" Text="{Binding Path=Name}" Margin="0, 5, 0, 0" HorizontalAlignment="Center" TextWrapping="Wrap" />
</Grid>
</Button>
</StackPanel>
<GridSplitter Grid.Row="1" Background="#DDDDDD" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>
Ok, this is all cool and well. In my current design, I am using ItemsControl and displaying a list of images. Since such a list can exceed the width of the window I wanted to add ScrollViewer around the StackPanel where the VerticalScrollBar is disabled (since I only want it to flow from left to right, I only need the HorizontalScrollBar).
After adding the ScrollViewer:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="120"/>
<RowDefinition Height="3" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<ScrollViewer>
<StackPanel Orientation="Horizontal">
<Button Margin="6" VerticalAlignment="Stretch" Width="{Binding Path=ActualHeight, Mode=OneWay, RelativeSource={RelativeSource Self}}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Source="http://blog.joeclarmusic.com/images/rss-icon.jpg" />
<TextBlock Foreground="Black" TextAlignment="Center" Grid.Row="1" FontSize="11" Text="{Binding Path=Name}" Margin="0, 5, 0, 0" HorizontalAlignment="Center" TextWrapping="Wrap" />
</Grid>
</Button>
</StackPanel>
</ScrollViewer>
<GridSplitter Grid.Row="1" Background="#DDDDDD" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" />
</Grid>
Image of the above when running in kaxaml 1.7.1 in my computer: jonatan.nilsson.is/wpf_with_scrollviewer.jpg
If you run it in Kaxaml (or in a WPF window/page) your button will now keep on getting bigger and bigger (both width and height). The only change I have done is add ScrollViewer around the StackPanel. everything else is the same so why does it keep on getting bigger when inside a scrollviewer?
What am I doing wrong here?
Edit:
Added an image of the outcome from the second example.
Ok, I found a solution. This “behavior” occurs if the following condition are met:
You can test this very easily. If you remove everything inside the Button.Content except for the image, the whole thing “almost” works (the button will not become smaller if you make the row height smaller using the GridSplitter but it will grow bigger).
However if you then add
Margin="0, 0, 0, 1"to the Image, then the same behavior occurs as before (that is, it grows infinitely).What is happening is basically this:
Basically, because the behavior of the image is to always keep it’s ratio. To work around this “behavior” is to make the Button content’s be wider than it is in height. If the Button contents width is higher than it’s height, then the Binding will force it’s width lower. This somehow makes the image behave correctly.
In my second example, adding for example this:
To Image will fix the issue of it’s never-ending growth.
I’m not sure if I explained this very well so please comment if you have suggestions that might improve this explanation.