Resizing image makes grid getting out from window - c#

I have a grid containing an Image (with 2 rows top and bot that I will use later) and another grid containing 4 radio button.
When I resize, if the grid's height is greater than image, I have 2 whites rows around the image :
But if the height is smaller, the image is not correctly displayed and my buttons disappear :
What can I do to keep buttons on screen and add white columns right and left to see the entire image ?
There is my code :
<Grid Grid.Column="2">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Image Grid.Row="1"
Source="{Binding Picture}"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<Grid Grid.Row="3">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<RadioButton Grid.Column="0" Grid.Row="0" Background="Red" Content="Point 1" IsChecked="{Binding SelectedPointIndex, ConverterParameter=1, Converter={StaticResource IndexBooleanConverter}}" />
<RadioButton Grid.Column="1" Grid.Row="0" Background="Green" Content="Point 2" IsChecked="{Binding SelectedPointIndex, ConverterParameter=2, Converter={StaticResource IndexBooleanConverter}}"/>
<RadioButton Grid.Column="1" Grid.Row="1" Background="Blue" Content="Point 3" IsChecked="{Binding SelectedPointIndex, ConverterParameter=3, Converter={StaticResource IndexBooleanConverter}}"/>
<RadioButton Grid.Column="0" Grid.Row="1" Background="Yellow" Content="Point 4" IsChecked="{Binding SelectedPointIndex, ConverterParameter=4, Converter={StaticResource IndexBooleanConverter}}"/>
</Grid>
</Grid>

You have simple layout problem. If you want something to take guaranteed space, use Auto, it take precedence over stars (stars are distributing leftover space, they get nothing if there is none).
You need following layout:
<Grid> <!-- high level container to ensure buttons grid is visible -->
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="auto" /> <!-- this row take precedence over first one -->
</Grid.RowDefinitions>
<Grid Grid.Row="0" ... > <!-- image grid -->
...
<Image ... />
</Grid>
<Grid Grid.Row="1"> <!-- buttons grid -->
...
<RadioButton ... />
</Grid>
</Grid>
And demo

For row with the image set <RowDefinition Height="*"/> instead of <RowDefinition Height="auto"/>. If you would like to leave spaces between image and radio button, I see your additional rows, set its height to fixed size.
Explanation:
'auto' guarantee that row of the grid will has height equals to height of the child content. If you would like to affect to size content via size of the parent control dynamically, you should use 'N*', where N - number.
For instance:
<Grid.RowDefinitions>
<RowDefinition Height="*"/> <!-- 25% of the rest of space -->
<RowDefinition Height="2*"/> <!-- 50% of the rest of space -->
<RowDefinition Height="*"/> <!-- 25% of the rest of space -->
<RowDefinition Height="auto"/> <!-- As result is static value. Height equals to height that's needed to display child content -->
</Grid.RowDefinitions>

Related

Expander combined with GridSplitter

I’m trying to split my WPF window into two “areas”, top and bottom.
The top area contains a grid.
The bottom area contains an expander.
Between the two areas should be a GridSplitter which the user can use to resize the areas.
The content of each area should use the full high of the area.
By default, the expander is expanded.
When the user closes the expander, the bottom area should reduce its height to the height of the collapsed expander.
This is my code:
<Window
x:Class="App.Shell"
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"
Title="Shell" Height="800" Width="1200">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid Name="MainContentGrid">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Top area -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0">1</Button>
<Button Grid.Row="1" Grid.Column="0">2</Button>
<Button Grid.Row="0" Grid.Column="1">3</Button>
<Button Grid.Row="1" Grid.Column="1">4</Button>
</Grid>
<GridSplitter Grid.Row="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Top"
Background="Black"
ShowsPreview="true"
ResizeDirection="Rows"
Height="5"></GridSplitter>
<!-- Bottom area -->
<Expander Grid.Row="1" Margin="0,5,0,0" IsExpanded="True" Height="Auto" VerticalAlignment="Stretch">
<Border Background="Red" Height="Auto" MinHeight="100" VerticalAlignment="Stretch"></Border>
</Expander>
</Grid>
<!-- Application Status Region -->
<ContentControl prism:RegionManager.RegionName="{x:Static local:RegionNames.StatusRegion}" Grid.Row="1" />
</Grid>
</Window>
Two things are not working:
The expander does not all available space (does not change its height)
When I close the expander, the GridSplitter does not allow the top area to use all the space available.
How can I make this work?
Once you interact with GridSplitters they set concrete relative or absolute Height/Width values on the grid row/column definitions. So once you collapse the Expander you should set its row's Height to GridLength.Auto.

DockPanel does not constrain height

I am trying to limit the height of a DockPanel (well the content acually) to the remaining UserControl Height with a ScrollViewer in it to scroll if its too big.
I have a window wich uses a ContentController to hold the different UserControls
<Window>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<!-- 0 Menu -->
<RowDefinition Height="auto"/>
<!-- 1 Header -->
<RowDefinition Height="65"/>
<!-- 2 Content -->
<RowDefinition Height="*"/>
<!-- 3 Space -->
<RowDefinition Height="10"/>
<!-- 4 Status line -->
<RowDefinition Height="auto"/>
<!-- 5 Space -->
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<!--...-->
<ContentPresenter Content="{Binding Path=MainWindowContent}" Grid.Column="0" Grid.Row="2"/>
<!--...-->
</Grid>
</Window>
The UserControl wich I having trouble with is just a search for users and the output of the results. It does look like this:
<UserControl>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto"/>
<ColumnDefinition Width="12"/>
<ColumnDefinition Width="auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
</Grid.RowDefinitions>
<Grid Grid.Column="1" Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Border Grid.Column="0" Grid.Row="0">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition Width="20"/>
<ColumnDefinition Width="200"/>
<ColumnDefinition />
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="25"/>
<RowDefinition Height="auto" />
<RowDefinition Height="10" />
<RowDefinition Height="auto"/>
<RowDefinition Height="10"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!-- input fields -->
<DockPanel Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="6" LastChildFill="True" VerticalAlignment="Stretch" Background="{StaticResource PrimaryCorporateBrush}">
<TextBlock Style="{StaticResource HeadlineOutputLabel}" DockPanel.Dock="Top"/>
<Separator Opacity="0" Height="10" DockPanel.Dock="Top"/>
<TextBlock Visibility="{Binding Path=HasResult, Converter={StaticResource Bool2RevertedVisibility}}" Margin="10" DockPanel.Dock="Top"/>
<ScrollViewer VerticalScrollBarVisibility="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Visibility="{Binding Path=HasResult, Converter={StaticResource Bool2Visibility}}">
<ItemsControl ItemsSource="{Binding Path=Members}" VerticalAlignment="Stretch">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border Tag="{Binding}">
<!-- Result Element -->
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</DockPanel>
</Grid>
</Border>
</Grid>
<Grid Grid.Column="3" Grid.Row="1">
<!-- info display -->
</Grid>
</Grid>
</UserControl>
I intent to limit the Results ScrollViewer height to the remaining visible space of the window, and if the results exceed it to display a scrollbar. But right now the DockPanel keeps extending the ScrollViewer and nested ItemsControl height till all elements are placed but does NOT show the ScrollBar.
I am a bit lost here why it does that, shouldn't the DockPanel limit the Height to the visible space? tried it with putting buttons instead of ItemsControl, nothing no ScrollBar.
I found the solution!
Further up in the Grid structure there was a row set to "auto" instead of "*" and ScrollViewer seems to only function properly with latter.

How to adjust control width and height according to windows width and height in WPF

Hi I am new to WPF programming.
I am having a window with its width and height according to my window width and height.
TblWind.Height = System.Windows.SystemParameters.FullPrimaryScreenHeight; //(768)
TblWind.Width = System.Windows.SystemParameters.FullPrimaryScreenWidth; //(1024)
Now i am adding Grid inside this window but want to adjust its height and width on the basis of windows height and width i.e 4 rows and each should take only 5% of windows height
Similarly 2 columns each width should be 5% of windows column
<Grid.RowDefinitions>
<RowDefinition Height=".5*" ></RowDefinition>
<RowDefinition Height=".5*"></RowDefinition>
<RowDefinition Height=".5*"></RowDefinition>
<RowDefinition Height=".5*"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"></ColumnDefinition>
<ColumnDefinition Width=".5*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Label Grid.Row="0" Grid.Column="0" Content="Name:"></Label>
<Label Grid.Row="1" Grid.Column="0" Content="Name:"></Label>
<Label Grid.Row="2" Grid.Column="0" Content="Name:"></Label>
<Label Grid.Row="3" Grid.Column="0" Content="Name:"></Label>
<TextBox Grid.Row="0" Grid.Column="1" ></TextBox>
<TextBox Grid.Row="1" Grid.Column="1" ></TextBox>
<TextBox Grid.Row="2" Grid.Column="1" ></TextBox>
<TextBox Grid.Row="3" Grid.Column="1" ></TextBox>
</Grid>
But it is dividing window width in 2 parts with each taking 50% of width.
Please help.
Your proportional sizing just means that all row heights and column heights will be the same. It's not a percentage of it's measured size.
i.e.
<RowDefinition Height="0.5*"/>
<RowDefinition Height-"0.5*"/>
Just means that 50% of the size of the first row is equal to 50% of the size of the second row. That is, their heights are equal.
No different than if you said:
<RowDefinition Height="2*"/>
<RowDefinition Height="2*"/>
just means that twice the size of the first row is equal to twice the size of the second row.
If you want to constrain your grid to the top 20% of your window height (4 * 5% = 20%) and the left-most 10% of your window width (2 * 5% = 10%), then force that in a Grid itself, and then you can just allow your rows and columns to all have equal sizing.
<Window>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="1*"/> <!-- 1/5th (20%) of the height -->
<RowDefinition Height="4*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/> <!-- 1/10th (10%) of the width -->
<ColumnDefinition Width="9*"/>
</Grid.ColumnDefinitions>
<!-- now we have a dedicated cell for your grid... -->
<Grid Grid.Row="0" Grid.Column="0">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- duplicate your content here... -->
</Grid>
</Grid>
</Window>

How to Wrap a TextBlock in a Horizontal StackPanel

I have a series of TextBlocks that all need to have their text wrapped, but when placed in a Horizontal StackPanel none of the TextBlock's text is wrapped. Originally I just had a StackPanel of several TextBlocks which worked fine, but I added a bullet to each TextBlock for easier reading, and therefore with my new implementation I lost the wrapping ability
<StackPanel Grid.Row="0" Orientation="Horizontal">
<TextBlock Text="•"/>
<TextBlock x:Name="InstructionsTextBlock1" Margin="12,0,12,0" TextWrapping="Wrap"
Text="{Binding Path=LocalizedResources.InstructionsPage_InstructionsTextBlock1, Source={StaticResource LocalizedStrings}}">
<LineBreak></LineBreak>
</TextBlock>
</StackPanel>
How might I wrap the text in the second TextBlock within the Horizontal StackPanel?
I ended up removing the StackPanel implementation all together, and creating a grid whereby I had 2 Columns and enough Rows for each bullet/textblock combination. I then set the first column to a small width, and the other column to the remaining width. I then added each bullet/textblock combination accordingly.
<ScrollViewer>
<Grid Margin="12,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".025*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="•"/>
<TextBlock Grid.Row="0" Grid.Column="1" x:Name="InstructionsTextBlock1" Margin="12,0,12,0" TextWrapping="Wrap"
Text="{Binding Path=LocalizedResources.InstructionsPage_InstructionsTextBlock1, Source={StaticResource LocalizedStrings}}">
<LineBreak></LineBreak>
</TextBlock>
...
</Grid>
</ScrollViewer

WPF Expander Not Expanding

I'd like to create a custom WPF accordion-like control without using WPF toolkit... After some searching it seems like the best approach would be to use an Expander... so I wanted to just see if I could get some sort of basic functionality like getting a row to expand upward to show some content when it is expanded and then to have it collapse and hide that content. It seems like it should be pretty straight-forward but my expander never expands. Here's my basic example:
<Grid Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="215"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<Expander Grid.Row="3" Grid.ColumnSpan="2" Header="More Options" ExpandDirection="Down" Background="Red" IsExpanded="False">
<StackPanel Height="300">
<CheckBox Margin="4" Content="Option 1" />
<CheckBox Margin="4" Content="Option 2" />
<CheckBox Margin="4" Content="Option 3" />
</StackPanel>
</Expander>
</Grid>
Update your RowDefinitions. Currently, the Row that the Expander is in is hard-coded to have a Height of 24. Make it Auto.
<Grid.RowDefinitions>
<RowDefinition Height="30"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="1*"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>

Categories

Resources