Silverlight - Auto-resize textbox to fill up empty space - silverlight

Ok this is what I wish to do.
I have a resizeable window which has 3 controls in same row in flowing order: textBlock, textBox and button.
textBlock and button have dynamic texts. So theirs size depends upon text inside.
Now what I wish to do is that textBox in the middle is always filling up all empty space between textBlock and button.
How do I do that?
I tried with the following code but it doesn't work because of fixed width in 1. and 3. column.
<Grid Margin="0,0,5,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" HorizontalAlignment="Left" Text="Text1"/>
<TextBox Grid.Column="1"/>
<Button Grid.Column="2" Content="Button1" HorizontalAlignment="Center"/>
</Grid>

You can use Auto for the two outer column widths instead of specifying the width
<Grid Margin="0,0,5,0" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="Text1" />
<TextBox Grid.Column="1"/>
<Button Grid.Column="2" Content="Button1" />
</Grid>
You probably don't need the HorizontalAlignment in the columns either

Related

Width of Textbox, which placed in grid column, extends when inserting long text

When I put a Textbox in a grid column like below
<StackPanel>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" MinWidth="115"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="90"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="hello"/>
<TextBox Grid.Column="1" />
<Button Grid.Column="2" Content="push me"/>
</Grid>
</StackPanel>
I get proper result, i.e. textbox width is get from parent grid
But when I type a long text, the textbox starts exceeding its column and it stops extending after several extra letters
To .Net 4.6.2, I get same result but changing to .Net 4.7.2 the problem is solved i.e. the textbox width is not changing.
My software is compiled .Net 4.0, is there a solution to solve this for lower .net than 4.7.2?
Tried Pavel's first idea: removing stackpanel and adding another grid row in, still not working in .net 4.6.2
Tried Pavel's second idea: making the width of first column "Auto" instead of "1*". This works, the textbox doesn't extend (.net 4.6.2), however I really wanted the first and second column be responsive to resize.
You can solve this be removing the StackPanel and adding RowDefinition to Grid. You can also set TextWrapping="Wrap" for TextBox for wrapping a long text
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="90"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="0" Text="hello" MinWidth="115"/>
<TextBox Grid.Column="1" TextWrapping="Wrap"/>
<Button Grid.Column="2" Content="push me"/>
</Grid>
StackPanel Y dimension is constrained to content, it will be automatically expanded to its content, more details can be found at panels overview
To me this is a bug that Textbox text size can change its parent width (grid width). This is happening in VS2019 .Net 4->4.6.2 but not in and after .Net 4.7.2.
For anybody faces this problem, I found below workaround by defining an invisible grid which contains textblocks. I get the widths of columns and give them to controls placed in a StackPanel.
<some container>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" MinWidth="115"/>
<ColumnDefinition Width="3*" />
<ColumnDefinition MinWidth="90"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="0"/>
</Grid.RowDefinitions>
<TextBlock x:Name="C0" Grid.Column="0" />
<TextBlock x:Name="C1" Grid.Column="1" Margin="5"/>
<TextBlock x:Name="C2" Grid.Column="2" />
</Grid>
<StackPanel Orientation="Horizontal">
<TextBlock Width="{Binding ElementName=C0, Path=ActualWidth }" Text="hello" />
<TextBox Width="{Binding ElementName=C1, Path=ActualWidth }" Margin="5" />
<Button Width="{Binding ElementName=C2, Path=ActualWidth }" Content="push me"/>
</StackPanel>
</some container>
The margin should be the same for column in grid and control in StackPanel (see second column).

Why doesn't a textbox stretch inside stackpanel WPF?

<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="49*" />
<ColumnDefinition Width="25*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" Margin="30" VerticalAlignment="Center">
<StackPanel Orientation="Horizontal">
<TextBlock Margin="0,0,5,0" Text="Username:" />
<TextBox HorizontalAlignment="Stretch"/>
</StackPanel>
</StackPanel>
--Result image--
Im trying to make it so that the textbox will fill the rest of the space inside the current StackPanel.
however the "Stretch" propety doesn't seem to work - why is that?
Is there a different way do it or what am I doing wrong?
A StackPanel always tries to achieve the minimum possible height/width, depending on orientation; therefore, Stretch has no effect. You might want to use a DockPanel instead, which allows children to stretch:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25*" />
<ColumnDefinition Width="49*" />
<ColumnDefinition Width="25*" />
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1"
Margin="30"
VerticalAlignment="Center">
<DockPanel>
<TextBlock DockPanel.Dock="Left" Margin="0,0,5,0"
Text="Username:" />
<TextBox HorizontalAlignment="Stretch"/>
</DockPanel>
</StackPanel>
</Grid>

Specify a width for a grid column

I'm using a grid to define a form with this column template :
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="3*" />
</Grid.ColumnDefinitions>
But I need for a specific row to use another column template :
<Label Grid.Column="0" Grid.Row="4">N°</Label>
<TextBox Grid.Column="1" Grid.Row="4" Name="idNum"></TextBox>
<ComboBox Grid.Column="2" Grid.Row="4" Name="idVoie" SelectedValuePath="Key" DisplayMemberPath="Value" SelectedValue="."></ComboBox>
<TextBox Grid.Column="3" Grid.Row="4" Name="idAdr"></TextBox>
with the first three field being 1* and the last field using the free space.
Of course, I can't specify the width directly in the field with percent.
Thanks for your help
You can use a nested grid for that particular row, which spans all four columns of your outer grid:
<Grid Grid.Column="0" Grid.Row="4" Grid.ColumnSpan="4">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="5*" />
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0">N°</Label>
<TextBox Grid.Column="1" Grid.Row="0" Name="idNum"></TextBox>
<ComboBox Grid.Column="2" Grid.Row="0" Name="idVoie" SelectedValuePath="Key" DisplayMemberPath="Value" SelectedValue="."></ComboBox>
<TextBox Grid.Column="3" Grid.Row="0" Name="idAdr"></TextBox>
</Grid>
Note I'm assuming when you refer to 1* you mean as relative to the grid you already have, i.e. the same size as the first and third columns. Therefore you have a total of 8* across the row, and I've calculated the relative widths for your row to be 1*, 1*, 1*, 5*.

WPF Grid - Shrink one column on window resize to keep all content on screen

I have a 5 column grid in WPF which displays some dynamic data. Columns 1,2 and 4 are fixed width as they are effectively labels, but 2 and 5 can be of different lengths.
Column 3 should wrap to make sure all content is shown but can expand to a maximum width of 390. But column 5 should remain on a single line. When I resize the window, everything must remain on screen without a horizontal scrollbar. The middle (3rd) column should shrink down to keep the 4th and 5th columns on screen.
Current behaviour: Column 3 will wrap when the contents expand beyond 390, but resizing the window will not cause this column to resize, but will cause column 5 then 4 disappear off screen.
Here's the code so far:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="auto" />
</Grid.ColumnDefinitions>
<Grid x:Name="ListItemControl"
Grid.Column="0"
MinHeight="50"
Width="auto"
VerticalAlignment="Top">
<Border Background="LightBlue"
Margin="1,0,1,1" />
<Grid VerticalAlignment="Center"
Margin="20,0,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40" />
<ColumnDefinition Width="130" />
<ColumnDefinition Width="*"
SharedSizeGroup="col2" />
<ColumnDefinition Width="150" />
<ColumnDefinition Width="auto"
SharedSizeGroup="col4" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition MinHeight="50" />
</Grid.RowDefinitions>
<TextBlock Grid.Column="0"
Grid.Row="0"
Margin="0,10,0,10"
Text="Due" />
<TextBlock Grid.Column="1"
Grid.Row="0"
Margin="0,10,10,10"
Text="Some Date" />
<TextBlock Grid.Column="2"
Grid.Row="0"
Margin="0,10,30,10"
Text="There is some potentially long text here. This is a placeholder and should wrap."
TextWrapping="Wrap"
MaxWidth="390" />
<TextBlock Grid.Column="3"
Grid.Row="0"
Margin="0,10,10,10"
Text="Who's responsible" />
<TextBlock Grid.Column="4"
Grid.Row="0"
Margin="0,10,10,10"
Text="Name - could be a very long name" />
</Grid>
</Grid>
</Grid>
Any help greatly appreciated!
Your ListItemControl Grid is inside another Grid with a single column, dont know the reason. Remove that parent Grid and you are done.

Lock element on the right

I have two textboxes in my app, with a variable lenght. One is on the left, the other one on the right. By default their width is pretty little, 30 px. But as they contain a lot of numbers, the textbox on the left shifts the right one and enlarges the window (same thing when the right textbw contains too many numbers). To avoid this, I would like to stabilize the right textbox on the right, even if its width rises.
I've tried to play with the columns size, but not.
<Grid Grid.Row="2">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="170" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="10" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" MinWidth="30" Margin="0,0,0,0" Name="maxGmapWest" Text="{Binding Path=Options.MaxGmapWest, ElementName=Window, Mode=OneWay, Converter={StaticResource StringToDoubleConverter}}" PreviewTextInput="Tab1_PreviewTextInput" Width="auto" />
<TextBox Grid.Column="3" MinWidth="30" Margin="230,0,0,0" Name="maxGmapEast" Text="{Binding Path=Options.MaxGmapEast, ElementName=Window, Mode=OneWay, Converter={StaticResource StringToDoubleConverter}}" PreviewTextInput="Tab1_PreviewTextInput" Width="auto" HorizontalAlignment="Left" />
</Grid>
Try something like that markup
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ScrollViewer Grid.Column="0" Width="auto" MinWidth="50" VerticalScrollBarVisibility="Auto" Margin="0,0,0,0" HorizontalAlignment="Left" MaxHeight="40" >
<TextBox Name="maxGmapWest" TextWrapping="Wrap" />
</ScrollViewer>
<ScrollViewer Grid.Column="1" HorizontalAlignment="Right" VerticalScrollBarVisibility="Auto" MinWidth="50" Margin="0,0,20,0" MaxHeight="40">
<TextBox Name="maxGmapEast" TextWrapping="Wrap" />
</ScrollViewer>
</Grid>
maxwidth for textbox=width of column, fixed max height and using ScrollViewer for large text

Resources