The following simple XAML puts a border on the base of a grid inside a scroll viewer and links the grid's width to the value of a slider.
<Window x:Class="BorderWidth.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="DrawBorder">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="50"/>
<RowDefinition Height="50"/>
</Grid.RowDefinitions>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<Grid Height="100" VerticalAlignment="Top" HorizontalAlignment="Left" Width="{Binding Value, ElementName=slider}">
<Border BorderBrush="Gray" BorderThickness="0,0,0,1"/>
</Grid>
</ScrollViewer>
<TextBox Grid.Row="1" HorizontalAlignment="Center" VerticalAlignment="Center" Text="{Binding Value, ElementName=slider}"/>
<Slider x:Name="slider" Minimum="124000" Maximum="126000" Grid.Row="2" VerticalAlignment="Center" Margin="10"/>
</Grid>
</Window>
While the width is less than 125000 the border shows, but after that value it vanishes. There is no maximum width mentioned in the documentation for the border control and the maximum width for a control in general is documented to lie somewhere between Single.MaxValue and Double.MaxValue, i.e. far far larger than 125000. Is this 125000 upper bound a bug; or is it documented somewhere?
Related
I only have the following so far
<Grid>
<DockPanel Background="Red">
<DataGrid DockPanel.Dock="Bottom" Height="357"/>
<StackPanel Background="Gray" DockPanel.Dock="Top" />
</DockPanel>
</Grid>
I want this layout to be retained when the program is enlarged;
and not like it is now when I make it big:
How can i make this?
Is it that, what you have wanted? By default the DockPanel.LastChildFill property is set to true. So if you enlarge the window, StackPanel in your case was enlarged.
<Grid>
<DockPanel Background="Red">
<StackPanel Background="Gray" MinHeight="75" DockPanel.Dock="Top" />
<DataGrid DockPanel.Dock="Bottom"/>
</DockPanel>
</Grid>
Take a look at grids, you can specify the height of the first row to 357 if you wish but Auto will just adjust to the contents on that row for you. * means fill the remaining space of the grid
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Grid.Row="0"/>
<DataGrid Grid.Row="1"/>
</Grid>
I have the following XAML source to demonstrate what I am working on.
I want, when resizing the group vertically, is to have the first groupbox expand, up to its max height, then, when that is reached, expand the third groupbox.The third groupbox has a min height property, as well.
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" x:Name="Screen_1_Name"
x:Class="TestExpansionScreens.Screen_1"
Width="400" Height="400">
<Grid x:Name="LayoutRoot" Background="White" Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<GroupBox Header="Thing1" Background="LightGreen" Grid.Row="0" Grid.Column="0" MaxHeight="350">
<Button Content="Stuff1" />
</GroupBox>
<GroupBox Header="Thing2" Background="LightBlue" Grid.Row="1" Grid.Column="0">
<TextBox Text="Stuff2" Height="60" />
</GroupBox>
<GroupBox Header="Thing3" Background="Pink" Grid.Row="2" Grid.Column="0">
<TextBox Text="Stuff3" />
</GroupBox>
</Grid>
</UserControl>
Normally, when I just want a single control expanded to fill the available space, I use a DockPanel. I've built this example with all kinds of assortments of grids and dockpanels, however, I have been unable to resolve how to make it work. Any idea on how to make it happen?
Thanks
You have to set the MaxHeight on your first RowDefinition, not on the GroupBox. The row will grow up to that height and then all excess space will be occupied by the third row. You can also add a MinHeight to the third row.
<Grid x:Name="LayoutRoot" Background="White" Margin="0,0,0,0">
<Grid.RowDefinitions>
<RowDefinition MaxHeight="350" />
<RowDefinition Height="Auto"/>
<RowDefinition MinHeight="150" />
</Grid.RowDefinitions>
<GroupBox Header="Thing1" Background="LightGreen" Grid.Row="0" Grid.Column="0">
<Button Content="Stuff1" />
</GroupBox>
<GroupBox Header="Thing2" Background="LightBlue" Grid.Row="1" Grid.Column="0">
<TextBox Text="Stuff2" Height="60" />
</GroupBox>
<GroupBox Header="Thing3" Background="Pink" Grid.Row="2" Grid.Column="0">
<TextBox Text="Stuff3" />
</GroupBox>
</Grid>
I can't figure out how to manage properly the width of a grid column with a user control in one of its cell. I have this xaml for a window:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Content="Button" Width="100" HorizontalAlignment="Left"/>
<TextBox Grid.Row="1" />
<local:UserControl1 Grid.Row="2"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
and the user control is a drawing set to stretch as needed:
<UserControl x:Class="WpfApplication1.UserControl1"
Height="auto" Width="auto">
<Grid Background="Aqua">
<Path Fill="Coral" Stroke="Black" StrokeThickness="1"
Stretch="Uniform"
HorizontalAlignment="Left" VerticalAlignment="Top">
<Path.Data>
<RectangleGeometry Rect="40,20, 140,30" RadiusX="10" RadiusY="10" />
</Path.Data>
</Path>
</Grid>
</UserControl>
To help I have set the user control background in blue.
I would like to have the width of the column ignoring the "natural" size of the user control. I mean I would like the user control to not determine the width during the layout of the column, but to adjust its width to whatever is the width of the column.
In the example, initially the Grid would set the column width to the value of the button, and the user control would use the column width to resize itself. Then if a long text is entered in the Textbox, as soon as the Textbox starts to be wider than the button, and the column starts to be resized as well, in turn the user control would adjust to maintain the same size than the column.
I've tried combinations of stretch values, and also have used MeasureOverride() in the user control. The latter doesn't work because the AvalaibleSize received is Infinity, not the column width.
I was able to achieve what (I believe) you're looking for by giving the TextBox a name, and binding the width of the UserControl to the ActualWidth of the TextBox. Here's the code for the Window's Grid:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto" />
<RowDefinition Height="auto" />
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Content="Button" Width="100" HorizontalAlignment="Left"/>
<TextBox Grid.Row="1" x:Name="entryTextBox" />
<local:UserControl1 Grid.Row="2"
Width="{Binding ElementName=entryTextBox, Path=ActualWidth}"
HorizontalAlignment="Left" VerticalAlignment="Top"/>
</Grid>
Hope that helps!
Old question, so it will probably not help OP anymore, but it may help others:
Put UserControl1 inside a Canvas. Then bind the Width to the ActualWidth of the parent Grid.
Example:
<Grid Name="mainGrid">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"></RowDefinition>
<RowDefinition Height="Auto"></RowDefinition>
</Grid.RowDefinitions>
<Something Grid.Row="0"/>
<Canvas Grid.Row="1">
<MyControl Width="{Binding ActualWidth, ElementName=mainGrid, Mode=OneWay}"/>
</Canvas>
</Grid>
The canvas will take the available width, but will never ask Grid for more.
The controls inside the canvas get no size from Canvas, so you must give it a size manually. In this case, we want to give it the size of the parent Grid.
I have the following in my XAML:
<Grid x:Name="LayoutRoot" Background="White">
<Grid.RowDefinitions>
<RowDefinition Height="20"/>
<RowDefinition Height="7"/>
<RowDefinition Height="57"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" FontSize="18">Title Text</TextBlock>
<Rectangle Grid.Row="1" Margin="0,2" Height="3" HorizontalAlignment="Stretch" Fill="#ff000000"/>
<Border Grid.Row="2" Margin="0" Padding="0" BorderBrush="Black" BorderThickness="1">
<TextBlock Margin="0" Padding="0" FontSize="55">123</TextBlock>
</Border>
</Grid>
The problem is that there is a space (about 10px) above the text in the bottom TextBlock. I can only seem to get rid of this space by using a much smaller font size.
Does anyone have an idea of why this space is showing up, and what I can do about it?
Thank you.
I believe it is because the default VerticalAlignment on a TextBlock is Stretch. Try setting it to Center:
<TextBlock Margin="0" Padding="0" FontSize="55" VerticalAlignment="Center">123</TextBlock>
If you really need to nudge it up you could add a negative top margin.
I'm having a problem, visible at runtime and in Expression Blend, where the text blocks (not text boxes, buttons, or custom controls) in my layout grid keep pushing themselves outside their cells, rendering them invisible. If I touch any of their properties in Blend (such as incrementing and then decrementing one of the margins), they become visible in Blend, but still not at runtime. Below is a screenshot showing the phenomenon in Blend. You see the design guides pointed to where the control should be, but its actual location above the top of the canvas.
Controls are offset in Blend http://tinyurl.com/y9ttscf
Update:
Below I've posted the XAML, with the VisualStateGroups removed (since they add considerable complexity to the XAML and the problem manifests itself without them). The control selected above is "loginTextBlock" below.
<navigation:Page
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"
xmlns:navigation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Navigation"
mc:Ignorable="d" xmlns:UserControls="clr-namespace:MyClient.UserControls" xmlns:MyClient_Controls="clr-namespace:MyClient.Controls;assembly=MyClient.Controls" xmlns:controlsToolkit="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit" x:Class="MyClient.Views.Login"
d:DesignWidth="640" d:DesignHeight="480"
Title="Login"
>
<Grid x:Name="LayoutRoot">
<Grid HorizontalAlignment="Center" Margin="0,16,0,0" VerticalAlignment="Top">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock x:Name="loginTextBlock" HorizontalAlignment="Center" Style="{StaticResource HeaderTextStyle}" VerticalAlignment="Center" Text="Login" Grid.ColumnSpan="2" Margin="0,8"/>
<TextBlock x:Name="usernameTextBlock" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Row="1" Text="User name:" TextWrapping="Wrap"/>
<TextBox x:Name="usernameTextBox" HorizontalAlignment="Left" Margin="8,8,0,8" VerticalAlignment="Center" Width="175" Grid.Column="1" Grid.Row="1" TextWrapping="Wrap" TabIndex="0" FontSize="16" Height="28" Padding="2"/>
<TextBlock x:Name="passwordTextBlock" HorizontalAlignment="Right" VerticalAlignment="Center" Grid.Row="2" Text="Password:" TextWrapping="Wrap"/>
<PasswordBox x:Name="passwordBox" HorizontalAlignment="Left" Margin="8,8,0,8" VerticalAlignment="Center" Width="175" Grid.Column="1" Grid.Row="2" TabIndex="1" FontSize="16" Height="28" Padding="2"/>
<Button x:Name="okButton" Height="32" HorizontalAlignment="Center" Margin="0,16,0,0" VerticalAlignment="Top" Width="96" Content="OK" Grid.Row="3" TabIndex="2" Click="okButton_Click" Grid.ColumnSpan="2"/>
<UserControls:StatusTextBlockControl x:Name="verifyingStatusTextBlockControl" Margin="8,16,8,8" VerticalAlignment="Center" Grid.Row="4" HorizontalAlignment="Center" Grid.ColumnSpan="2" Text="Verifying credentials..."/>
<MyClient_Controls:LoginAttemptsCounter x:Name="loginAttemptsCounter" HorizontalAlignment="Center" Margin="8" VerticalAlignment="Center" Grid.ColumnSpan="2" Grid.Row="5" FirstFailureMessage="Please re-enter your Windows credentials.
After 2 more failed attempts, your account will be locked." Height="30"/>
</Grid>
</Grid>
</navigation:Page>
For some reason, when my "LoginAttemptsCounter" control is in the grid (at the bottom), it was messing up the TextBlock controls. Instead, I changed my layout to wrap the grid within a StackPanel and place the LoginAttemptsCounter in the StackPanel below the grid rather than in the grid's bottom row. That has worked.
The key thing is that my custom control can't be within the same container (either the StackPanel or the Grid) as the TextBlocks.