Silverlight - Dynamic Layout - silverlight

I have a Silverlight application that will run out of the browser. I want the layout to resize based on the size of the window. The layout is composed of a Grid. This Grid has a Canvas which hosts a Border, and other controls. The Canvas correctly resizes as the window resizes. However, the Border control seems to be a fixed size. How do I make the Border control stretch to the width of the Canvas and resize if the Window resizes? My code looks like the following:
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Canvas x:Name="myCanvas" Background="Lime">
<Border Canvas.Top="77" Border="Black" BorderThickness="2">
<TextBlock x:Name="myTextBlock" />
</Border>
</Canvas>
</Grid>
Thank you for your help!

Assuming you are wanting the Canvas to be bound to the first Grid.Column, then you can add RowDefinitions and then move the Border to outside the Canvas, then the following code should work.
(Only tested in WPF)
<Grid x:Name="LayoutRoot">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="77"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Canvas x:Name="myCanvas" Background="Lime" Grid.RowSpan="2">
</Canvas>
<Border Grid.Row="1" Border="Black" BorderThickness="2" VerticalAlignment="Top">
<TextBlock x:Name="myTextBlock" Text="Happy TEXT" />
</Border>
</Grid>
New stuff: <Grid.RowDefinitions>, Grid.RowSpan="2" to Canvas and Grid.Row="1" plus VerticalAlignment="Top" to Border.
Text added for testing.

Related

How to make TextBox fill all available space without later resizing to its content?

I have the following Grid with a TextBox in it:
<UserControl ...>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="30px"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="1px"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" Grid.RowSpan="3" AcceptsReturn="True"
TextWrapping="Wrap" HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<!-- content in other cells of the Grid's first column -->
</Grid>
</UserControl>
I want the TextBox to fill all space that is available on the control (width and height-wise) and should the user enter more text than fits into it I want its vertical scrollbar to become active, without resizing the TextBox. What happens instead is that the size of the TextBox changes to accomodate the content and the whole grid grows with it.
How do I achieve what I need?
Edit: Here's an illustration of what happens.
The above screenshot is of the situation when the content fits comfortably into the TextBox. The below screenshot is of the situation when there is not enough room to fit all content - the TextBox is then resized to fit it and this resizes also the grid that it is placed in, making it look broken.
Edit 2: The project that demonstrates this behavior is here.
I have managed to solve this by adding an invisible Border in the same cells of the Grid as the TextBox, then setting TextBox' Width and Height to ActualWidth and ActualHeight of that Border respectively:
<Border x:Name="b" Grid.Column="1" Grid.RowSpan="3"
HorizontalAlignment="Stretch"/>
<TextBox AcceptsReturn="True" TextWrapping="Wrap" Grid.Column="1"
Grid.RowSpan="3" Width="{Binding ActualWidth, ElementName=b}"
Height="{Binding ActualHeight, ElementName=b}"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
This then caused the TextBox to stay of fixed Height regardless of its content, but there was another problem with its Width: it grew when the interface was expanded, but didn't shrink afterwards, because of the underlying ScrollViewer. The trick was to set that ScrollViewer's HorizontalScrollBarVisibility to Disabled, instead of Hidden as I had done previously.
I pushed changes of the example project to GitHub, so the solution is now available here.
The TextBox doesn't fill the Grid. You can confirm this yourself by specifying a Background for the Grid:
<UserControl>
<Grid Background="Yellow">
...
This is because the height of the Grid is 30 px + whatever the height of the TextBox is + 1 px. For the contents of the row 2 or 3 to fill the Grid, you need to change the Height of at least one of the RowDefinitions to *:
<UserControl>
<Grid Background="Yellow">
<Grid.RowDefinitions>
<RowDefinition Height="30px"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
<RowDefinition Height="1px"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="1" Grid.RowSpan="3" AcceptsReturn="True"
TextWrapping="Wrap" HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Visible" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</UserControl>

How to resize the usercontrol in wpf resizing

In my wpf project I have one main window(Mainwindow.xaml) file and remaining all windows are user controls. If I click any menu of the mainwindow.xaml then the corresponding usercontrols will appear in the mainwindow.xaml form.
My requirement is, when the usercontrol window is resized, I need to resize all controls width (i.e textboxes,comoboxes,..etc). How can I achieve this.
First of all, the components you need to resize dynamically should not have fixed sizes. You should put everithing into Grid and set width/height to "Auto"/"x*"/ Alignment to stretch...
<UserControl ...>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*" />
<ColumnDefinition Width="2*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*"/><!--2/5 of total height-->
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Column="1" Grid.Row="1">Text </TextBlock>
<TextBox Grid.Column="2" >Enter</TextBox>
<TextBox Grid.Row="2" Grid.ColumnSpan="2">Button 5 Button 5 Button 5 Button 5</TextBox>
</Grid>
</UserControl>
Main
<Grid Width="Auto" HorizontalAlignment="Stretch">
<ContentControl ..." />
</Grid>

WPF:stretch to parent loop

In my WPF application I am trying to connect all the sizes to the app size. So the main grid stretches to the main window, the canvas - to the main grid etc. But this does not work. For example, ScrollViewer that is inside of the canvas, stretches to the main grid.
What is a solution?
Simple code for example:
<Window Height="400" Width="200" ...>
<Grid HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Canvas Grid.Row="0" Grid.Column="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<ScrollViewer HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
</ScrollViewer>
</Canvas>
</Grid>
</Window>
Just remove the canvas and it will work.
Basically, canvas has infinite size by default, so everything in canvas cannot be aligned, unless you specify size maually.
<Window Height="400" Width="200" ...>
<Grid>
<ScrollViewer>
</ScrollViewer>
</Grid>
</Window>
Note, that you dont have to specify Grid's Column and Row Definitions, if there's only single cell. it works by default. Also, Horizontal and Vertical Alignment hav value "Stretch" by default, so it does not have to be specified explicitelly as well.
Since there is nothing but scrollviewer inside the grid, you could remove the grid as well:
<Window Height="400" Width="200" ...>
<ScrollViewer>
</ScrollViewer>
</Window>

resize a WPF grid when window maximized to same portions as the window

i have a basic grid in my WPF application:
<Grid>
<Grid Height="260" HorizontalAlignment="Left" Margin="24,25,0,0" Name="grid1" VerticalAlignment="Top" Width="452">
<Border BorderBrush="Red" BorderThickness="6"></Border>
</Grid>
</Grid>
the grid is in the middle of the window.
When i maximize the window i want the grid to auto resize itself to the size of the window and stay with the same margin that i specified.
How do i do that ?
Do i have to calculate and resize the whole thing in the resize event?
i get from this:
to This (i dont want this):
i want the grid to resize to the same portions as it was , but for a full screen.
Remove Width and Height.
<Grid>
<Grid Margin="24,25">
<Border BorderBrush="Red" BorderThickness="6"></Border>
</Grid>
</Grid>
e: Added a second grid to make it identical to OP
You could host the Grid inside of another Grid with something like:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25" />
<RowDefinition />
<RowDefinition Height="25" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="25" />
<ColumnDefinition />
<ColumnDefinition Width="25" />
</Grid.ColumnDefinitions>
<!-- Main Grid -->
<Grid Grid.Row="1" Grid.Column="1">
<!-- Main Content -->
</Grid>
</Grid>
That would allow you to put all your content inside of the Main Grid, while maintaining a constant margin of 25 around all edges.

Viewbox containing a TextBlock seems to have minimum height

I'm trying to build a UI layout in WPF that can scale with the size of the window. The idea is to have a number of controls on the left, a number of controls on the right, and in the middle, have a line of text. It's OK if the line of text is cropped on the right. The main thing is that the aspect ratio of all of the controls is maintained.
That part is working fine. The problem is that the center line of text seems to have a minimum height; below this height, it will start clipping vertically. I want the text to keep shrinking if I make the window very thin. Even manually setting the FontSize on the TextBlock doesn't work.
Note that the controls on the left and right do not have a minimum width; they can shrink indefinitely.
My XAML is here. I'm using .NET 4.0.
<Window x:Class="TestWpfApp.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="75" Width="525">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Viewbox Grid.Column="0" Stretch="UniformToFill" Margin="2">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">A</Button>
<Button Grid.Column="1" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">B</Button>
<Button Grid.Column="2" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">C</Button>
<Button Grid.Column="3" Grid.Row="0" HorizontalAlignment="Center" VerticalAlignment="Center">D</Button>
</Grid>
</Viewbox>
<Viewbox VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="1" Stretch="UniformToFill" Margin="2">
<TextBlock>Here is a bunch of text that may prove to be interesting.</TextBlock>
</Viewbox>
<Viewbox Grid.Column="2" Stretch="UniformToFill" Margin="2">
<Button HorizontalAlignment="Center">X</Button>
</Viewbox>
</Grid>
</Window>
The problem is that you like the Viewbox clipping when it occurs horizontally but don't want any clipping vertically. In other words, you want UniformToFill until the horizontal clipping stops and then you want to switch to Uniform.
To get both of these behaviors you need an alternative to Viewbox. A while ago I wrote a prototype of just such a layout element in this Stack Overflow answer called ViewboxPanel:
Making a Viewbox scale vertically but stretch horizontally
I just tested it, and at least for your sample XAML, I think it does just what you want:
<local:ViewboxPanel VerticalAlignment="Top" HorizontalAlignment="Left" Grid.Column="1" Margin="2">
<TextBlock>Here is a bunch of text that may prove to be interesting.</TextBlock>
</local:ViewboxPanel>

Resources