I have a stackpanel that contains an expander control and below that 3 rows of buttons. Depending on logic the buttons may be collapsed. If enough buttons are collapsed to eliminate a row of them, I would like the expander to open up revealing more of it contents. I need it to open up depending on how much room is available below it.
Is there anyway to partially open up an expander to make use of additional space if it becomes available?
Thanks
Harold
I think what you are trying to do is simpler than you make it sound,
You need the right container/ panel to achieve what you are asking.
An example is like below
:-
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Expander Grid.Row="0"/>
<Button Grid.Row="1"/>
<Button Grid.Row="2"/>
<Button Grid.Row="3"/>
<Grid>
With the Grid Panel if you use auto when the control within gets collapsed so does the space and because the first Expander's Grid row is * it will adjust to fill and free space.
Related
In my WPF application, a database is filled with personal data.
Among them is if a person is alive, and if not, date and place of their death can be given. Where you can feed the data, I have a grid with two columns, in the left one is "place of death" text block, in the right is a TextBox. Same for date of death.
If you select the "Alive" check box, I tried hiding both TextBlocks and TextBoxes with a style trigger and Visibility.Collapsed setter inside them, which seems really inconvenient.
Is there any other approach to do this?
If you are using MVVM , you can bind the Visibility to a boolean and use a value converter to change it to collapsed.
Look for BooleanToVisibilityConverter.
You can play with the Height of Row to achieve your goal.
XAML
<Grid Grid.Column="2" Grid.Row="1" x:Name="MyGrid">
<Grid.RowDefinitions>
<RowDefinition Height="60" />
<RowDefinition Height="*" />
<RowDefinition Height="*" />
<RowDefinition Height="80" />
</Grid.RowDefinitions>
</Grid>
Code Behind: C#
MyGrid.RowDefinitions(2).Height = new GridLength(0);
Code Behind: VB.NET
MyGrid.RowDefinitions(2).Height = New GridLength(0)
I'm developing a Database system that needs to be resolution independent, some use screens that are still running at 1024 x 768, some use screens that are at 1920 x 1080 and others use everything in between.
I haven't done much work with WPF before so I'm sort of just starting out and attempting to get my head around height, widths and alignments.
What I have at the moment is one main window that holds an grid in which at the top there is a row for a label and some navigation buttons, as well as the time and the username of the person logged in. I then have a second row below that that holds a frame which I load pages into for the main navigation of the program.
In the pages I mainly use the grid layout, and occasionally the stack panel. One of the biggest problems I have come across is an issue like this;
In low resolutions this is common, where as in a higher resolution the buttons look fine;
This is the XAML code for the buttons within their parent grid;
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button Content="HR" Margin="10" Click="RunHrSystem" FontSize="18.667" />
<Button Content="Companies" Margin="10" Click="RunCompSystem" FontSize="18.667" Grid.Row="1" />
<Button Content="People" Margin="10" Click="RunPeopleSystem" FontSize="18.667" Grid.Row="2" />
<Button Content="IT Management" Margin="10" Click="RunITManagementSystem" FontSize="18.667" Grid.Row="3"/>
<Button Content="Sales" Margin="10" FontSize="18.667" Grid.Row="4" />
<Button Content="Buying" Margin="10" FontSize="18.667" Grid.Row="5" />
<Button Content="Estimating" Margin="10" FontSize="18.667" Grid.Row="6"/>
<Button Content="Design" Margin="10" FontSize="18.667" Grid.Row="7"/>
</Grid>
Is there anything obvious I am doing wrong here that is preventing the buttons from resizing according to a lower resolution? As I say I get this throughout my program when using buttons, as well as the rectangle shape and in some situations labels, where the bottom of the label will be cut off too.
Currently, you are declaring RowDefinitions to use *, this tells the row to use the height as a percentage of the available space. Therefore, if your resolution changes, your row heights will change.
Instead, you want the RowDefinition to be the height of the content. In this case, when the resolution changes, the row heights will not change.
<RowDefinition Height="Auto"/>
It'd be a good idea to put the grid in a ScrollViewer, just in case the grid becomes larger than the screen.
<ScrollViewer>
<Grid>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
...
In your particular example, I would instead use a StackPanel.
<ScrollViewer>
<StackPanel>
<Button ...
I guess it's a bad practice to hide existing buttons in a non-visible area. The user should scroll for accessing bottom buttons. If you need to support the low-resolution monitor, an app should adjust to the current resolution.
I guess the best way is decreasing the margin, set * for RowDefinitions and limit grid height to prevent huge stretching.
I have the following Grid setup in a WPF application.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="220" />
<RowDefinition Height="40" />
<RowDefinition Height="80" />
<RowDefinition Height="180*" />
</Grid.RowDefinitions>
<!-- some content -->
</Grid>
What I want is for the final row to take up as much height as available in its parent. But it does not seem to honor my '*' command in the final row definition.
Please note that I want all other row heights to be fixed..
Is this possible? If so how? Any help or pointers are appreciated..
place height="*" in last row.
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="220" />
<RowDefinition Height="40" />
<RowDefinition Height="80" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
What you have written should be fine (though as #Bolu commented, the 180* could be replaced with * in this case). If the content in the last row is not expanding to fill the available size, I would suspect one of the following:
The Grid may be nested somewhere below a layout panel that does not arrange its children to fill all available vertical space. For example, is one of the Grid panel's ancestors a StackPanel? A good way to test whether this is the culprit is to comment out the entire Grid and replace it with a Border with an easily distinguishable background (e.g., Magenta) and see if it occupies the entire area you expect the Grid to fill.
There may not actually be any content in the last row. Did you set the correct Grid.Row value correctly?
You may be overriding the layout behavior of the last row's content. Are you setting the content's VerticalAlignment to anything other than Stretch?
Remove the Height property from the last Row:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="220" />
<RowDefinition Height="40" />
<RowDefinition Height="80" />
<RowDefinition/>
</Grid.RowDefinitions>
<!-- some content -->
</Grid>
t may be a basic question. But I can't figure it out after several hours research.
I have an item detail page. I want to add another grid in it whenever the scrollview reaches the right bottom. Right now I partially achieved this goal by adding a column in the xaml and toggle its visibility property.
<Grid x:Name="body" Style="{StaticResource LayoutRootStyle}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Grid x:Name="dynamicGrid" Grid.Column="1" Grid.RowSpan="2" Visibility="Collapsed">
<Grid.RowDefinitions>
<RowDefinition Height="80"/>
<RowDefinition Height="360"/>
<RowDefinition Height="360"/>
</Grid.RowDefinitions>
<TextBlock .../>
<GridView .../>
<GridView .../>
</Grid>
And in code behind
if (//Reach the right side)
{
if (related.Visibility == Visibility.Collapsed)
{
related.Visibility = Windows.UI.Xaml.Visibility.Visible;
}
}
if (// Move away from right border)
{
related.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
}
It works to some point. But the animation is jumpy. Sometime, the scrollviewer even refuse to go back to the beginning. I guess the problem is when I adding/removing ui control at runtime, the scrollviewer doesn't handle it quite well.
I'm wondering is there a better way to achieve this feature? Any suggestion is welcomed.
You can add a child control in a grid by calling grid.Children.Add(newChildControl). You can also assign the child control to specific row/column/span by calling Grid.SetRow/Column/RowSpan/ColumnSpan.
My group is building an editor-type app in WPF. One thing we noticed is that on my WinXP machine, running with the "windows classic style" theme, the text on buttons is fits fine. However on my friend's machine, who's running with the "windows xp style" theme, the font size is bigger so text on buttons get clipped at the bottom.
Is there a way to handle this nicely, like automatically resizing controls to fit the text?
I hesitate to manually resize the button to fit his layout as anyone else can have totally different settings through the Display Properties and Accessibility Options.
Thanks!
A WPF button will automatically resize to fit the content that it has been given, however it will only do this when it is inside a container that does not enforce size and its size has not been set manually. To prove this mess around with the font size in the following code snippet:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Button
Grid.Column="1"
Grid.Row="1"
FontSize="24"
Content="QWERTY"/>
</Grid>
I guess that your buttons haven't resized because you have constrained them. To fix this you need to decide how you want them to resize (which can be very complicated when elements would overlap if they just grew blindly) and if none of the supplied panel types perform the growth behaviour that you are looking for then you may need to write your own that does.
Have you hardcoded element sizes using Width and Height properties? In WPF the recommended way to do this is to use the several layout containers.
The following is an example of a grid which lays two buttons at the bottom and a textbox at the top.
<Grid>
<Grid.RowDefinitions>
<!-- TextBox row with unspecified height. -->
<RowDefinition Height="*"/>
<!-- Button row with automated height so it resizes to
fit the content -->
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!-- Textbox on first row. -->
<TextBox Margin="3" Name="textBox1" Grid.Row="0" AcceptsReturn="True" />
<!-- StackPanel which lays the two buttons at the bottom horizontally.
RightToLeft is specified so that the first button appears on right.
-->
<StackPanel Grid.Row="1" HorizontalAlignment="Right"
Orientation="Horizontal" FlowDirection="RightToLeft">
<!-- The buttons. Only padding and margin are hardcoded so these
can resize to the contents -->
<Button Padding="3" Margin="3">OK</Button>
<Button Padding="3" Margin="3">Cancel</Button>
</StackPanel>
</Grid>