WPF, width of control change with window width change - wpf

In WPF application, a grid panel with 3 columns as defined below
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
There is a slider in the second column,the width of the slider needs to reduce when the window width reduces and at some point the slider needs to disappear (kind of responsive design).
I tried naming the second column and binding width of slider to "ActualWidth" property of the column, but it didn't help.
There is another way to handle window's size change event and do some adjustments. Any other simple way?
Update 1 :
Adding more of my code
<Grid VerticalAlignment="Top" HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<!-- some other elements in cell 0-->
<StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Center">
<Button Width="22" Height="22">
<Image Source="a.png"/>
</Button>
<Slider MinWidth="100" MaxWidth="320" Width="320"/>
<Button Width="22" Height="22" >
<Image Source="b.png"/>
</Button>
<!-- some other elements in cell 2-->
</StackPanel>
</Grid>

That's because the ActualWidth of a ColumnDefinition is not a DependencyProperty and ColumnDefinition doesn't notify when this property has changed.
Instead try grouping all your controls in column 2 inside a Grid and bind to the ActualWidth of the grid.

Assuming the slider is a generic WPF slider control, then simply placing the slider inside the second column should work, as by default the control should fill all available column space. Perhaps a style you have applied to the slider is affecting this functionality? The slider should fill up the column, and shrink down into nothingness as the window/column resizes if you use this code
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="250"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="250"/>
</Grid.ColumnDefinitions>
<Slider Grid.Column='1'></Slider>
</Grid>
EDIT:
Based on your new code, perhaps this might be more what you are after?
<DockPanel VerticalAlignment="Top">
<!-- Elements in cell 0-->
<Grid Width="250" DockPanel.Dock="Left"/>
<!-- Elements in cell 2-->
<Grid Width="250" DockPanel.Dock="Right"/>
<!-- Cell 1-->
<DockPanel>
<Button DockPanel.Dock="Left" Width="22" Height="22">
<Rectangle Fill="Blue"/>
</Button>
<Button DockPanel.Dock="Right" Width="22" Height="22" >
<Rectangle Fill="Blue"/>
</Button>
<Slider/>
</DockPanel>
</DockPanel>
The slider will resize and disappear accordingly, and the slider position will remain consistent during the resizing of the window

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).

AutoSizing of Usercontrol

For a WPF application I have a user control MyUsrCntrl with Height=300 and Width=300
When i place MyUsrCntrl in a window and set its size to 600x600 the user control get resized but the controls in that does not get resized ,
is there any solution for this.
If you want to extend and compress the height and Width of your Usercontrol then make the Parent Controls Height="*" and Width="*" and don't assign any height and width to your controls present inside UserControl. Something like:
<Grid Margin="4" Background="Orange">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0">
<TextBlock Text="It is fixed" Margin="1"/>
<Button Content="It is fixed"/>
</StackPanel>
<StackPanel Grid.Column="1">
<TextBlock Text="It is variable" Margin="1"/>
<Button Content="It is fixed" Margin="2"/>
</StackPanel>
</Grid>

Silverlight browse files control

I want to design a browse files control. Basically it is a textbox + button('...') + button ('upload')
Can I use a stackpanel for this? I want the two buttons to be on the right end of the panel. Upload button will be visible only if the textbox has text. The textbox should fill all the space.
Do you have an example hoe to put the first button('...') in the textbox itself?
Thanks a lot,
Radu
I would use a Grid instead. The StackPanel won't stretch the textbox.
<Grid >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="70"/>
<ColumnDefinition/>
<ColumnDefinition Width="26"/>
<ColumnDefinition Width="60"/>
</Grid.ColumnDefinitions>
<TextBlock Text="File Path:" TextAlignment="Right" VerticalAlignment="Center" Margin="0 0 10 0"/>
<TextBox Name="txtFilePath" Grid.Column="1" Margin="2"></TextBox>
<Button Name="btnPrompt" Content="..." Grid.Column="2" Margin="2"></Button>
<Button Name="btnUpload" Content="Upload" Grid.Column="3" Margin="2"></Button>
</Grid>

ZOrder behavior in WPF grid?

The code below contains a simple grid with a button in grid's middle column. The button width is (by intention) larger than column with it is placed into. Notice that the left part of the button is visible the right one is not. What do I have to do to get both left and right button parts invisible? Right part of the button is z-below the right grid column, but the left part of the button is z-above the left grid column. I need the left button part also to be hidden by the left grid column.
This is a simplified version of XAML where I am trying to animate kind of 'film strip'. Film should be placed z-below left and right grid column and z-above the middle part. The animation works nicely, but user see for a while controls on the left part she is not supposed to see as those should be 'covered' by the left grid column.
<Grid x:Name="LayoutRoot">
<Border Background="Yellow" x:Name="ContentBorder">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" >
<Button Content="Button" Margin="-20, 0, 0, 0" Width="240" Height="33"/>
</Grid>
</Grid>
</Border>
</Grid>
Try adding a ClipToBounds
<Grid x:Name="LayoutRoot">
<Border Background="Yellow" x:Name="ContentBorder">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"/>
<ColumnDefinition />
<ColumnDefinition Width="40"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="1" ClipToBounds="True" >
<Button Content="Button" Margin="-20, 0, 0, 0" Width="240" Height="33"/>
</Grid>
</Grid>
</Border>
</Grid>

Silverlight - Auto-resize textbox to fill up empty space

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

Resources