Why I cannot set canvas's width via binding method? - xaml

My UI elements' layout (nest relation) is:
toolbarGrid -> toolbarCanvas -> toolbarPanel -> some buttons
My purpose is to make animation of those buttons.
The issue is that I use Debug.Write() to monitor the Width and ActualWidth parameters of the UI elements. And I found that when App screen size is changed, only toolbarGrid size is changed accordingly. While the other UI elements' sizes are not changed at all, although I use Binding method to bind their Width and ActualWidth to toolbarGrid.
So how can I set their Width and ActualWidth so that they could change according to App screen's real size?
toolbarPanel width = 1920, actualWidth = 1920
toolbarGrid width = NaN, actualWidth = 1034
toolbarBackground width = 1920, actualWidth = 1920
toolbarCanvas width = 1920, actualWidth = 1920
<Grid x:Name="gridTotal">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Rectangle x:Name="recTangle1" Grid.Column="0" Grid.Row="0"/>
<Rectangle x:Name="recTangle2" Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="12"/>
<Grid x:Name="toolbarGrid" Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="12">
<Canvas x:Name="toolbarCanvas" Width="{Binding ElementName=toolbarGrid, Path=ActualWidth}">
<RelativePanel x:Name="toolbarPanel" Canvas.Top="0" Width="{Binding ElementName=toolbarGrid, Path=ActualWidth}">
<Image x:Name="toolbarBackground" Source="ms-appx:///Assets/MainPage/toolbar/toolbar-background2.png"
Width="{Binding ElementName=toolbarGrid, Path=ActualWidth}"
Height="{Binding ElementName=toolbarGrid, Path=ActualHeight}" Stretch="Fill" />
<Viewbox x:Name="vb2" Stretch="Uniform" RelativePanel.AlignHorizontalCenterWithPanel="True" Margin="20,0,20,0"
Height="{Binding ElementName=recTangle1, Path=ActualHeight}"
Width="{Binding ElementName=recTangle1, Path=ActualWidth}">
<Button x:Name="toolbarHistory" Style="{StaticResource toolbarImageStyle}">
<Image Source="ms-appx:///Assets/MainPage/toolbar/toolbar-history.png" Stretch="UniformToFill" />
</Button>
</Viewbox>
</RelativePanel>
</Canvas>
</Grid>
</Grid>

I tried to understand your problem. If the problem was that u like to Elements follow actual screen size this one works. I changed the XAML code and hoping that next solution works fine for you. I rid of the Canvas because that element cause the problem. Anyway, in this example u do not need it (unless u have planned some other use later). And also to set Row/Column Width/Height values is unneeded. Bindings are also unnessessary.
<Grid x:Name="gridTotal">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Rectangle x:Name="recTangle1" Grid.Column="0" Grid.Row="0"/>
<Rectangle x:Name="recTangle2" Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="12"/>
<Grid x:Name="toolbarGrid" Grid.Column="0" Grid.Row="8" Grid.ColumnSpan="12">
<RelativePanel x:Name="toolbarPanel" Canvas.Top="0">
<Image x:Name="toolbarBackground" Source="ms-appx:///Assets/MainPage/toolbar/toolbar-background2.png" Stretch="Fill" />
<Viewbox x:Name="vb2" Stretch="Uniform" RelativePanel.AlignHorizontalCenterWithPanel="True" Margin="20,0,20,0">
<Button x:Name="toolbarHistory">
<Image Source="ms-appx:///Assets/MainPage/toolbar/toolbar-history.png" Stretch="UniformToFill" />
</Button>
</Viewbox>
</RelativePanel>
</Grid>
</Grid>

Related

How to change whole Grid's background color for specific row

Something similar to this:
<Grid Background="Yellow" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="0"/>
</Grid.RowDefinitions>
</Grid>
But this would change the whole Grid. I just want to change the background color of specific row. How?
Add another Grid inside the Grid like this:
<Grid Background="Yellow" Width="300">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="0"/>
</Grid.RowDefinitions>
<Grid Background="Blue" Grid.RowSpan="2" Grid.Column="0"/>
</Grid>

Force a view to be square in shape

I am trying to create a UI in XAML for Xamarin Forms in which I have a frame (though I assume the answer would be the same for any type of view) inside of a grid. I want the frame to use full width available to it in the grid cell that it occupies, but I want to force it to be square in shape. So, I want the width to size automatically, and have the height set to match its actual width.
Here's what I have so far:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="13*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="1"/>
<Button Grid.Row="1" Grid.Column="1"/>
<Button Grid.Row="2" Grid.Column="1"/>
<Frame Grid.Row="0" Grid.Column="3" Grid.RowSpan="3" OutlineColor="Silver" HorizontalOptions="Fill">
<Image />
</Frame>
</Grid>
Currently, the frame correctly fills the available width, but the height is about the same as the total height of the 3 buttons to the left of it combined.
I was thinking that I maybe needed to bind the frame's HeightRequest to its actual width, but I don't know if that's possible, or how to do it if it is. If not, any other options?
Since you're setting the RowSpan of the frame to 3, even if you explicitly set the frame's HeightRequest to some small value, the frame will still take up the entire grid's height. So first you have to prevent that from happening. You could do that by containing the frame inside some other view.
Now to make the frame's height and width the same as it scales, you could use the container's SizeChanged event and set the frame's height and width requests accordingly.
Also note that Frame by default has a padding of 20.
Here's the sample code for the xaml:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="6*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="13*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="1"/>
<Button Grid.Row="1" Grid.Column="1"/>
<Button Grid.Row="2" Grid.Column="1"/>
<StackLayout x:Name="frmContainer" Grid.Row="0" Grid.Column="3" Grid.RowSpan="3" BackgroundColor="Orange">
<Frame x:Name="frm" OutlineColor="Silver" VerticalOptions="Center" HorizontalOptions="Center" Padding="0" BackgroundColor="Green"/>
</StackLayout>
</Grid>
And here's the constructor in the code-behind:
InitializeComponent();
frmContainer.SizeChanged += (s, e) =>
{
frm.HeightRequest = frmContainer.Width;
if (frmContainer.Width > frmContainer.Height)
{
frm.WidthRequest = frmContainer.Height;
}
else
{
frm.WidthRequest = frmContainer.Width;
}
};

Grid inside Stackpanel doesn't stretch

The width of the Rectangle is now 0.
if I set the ColumnDefinition to 200 or width in Rectangle tot 200, than I can see the Rectangle. But with the star it's not working.
I'm Trying to set the width of Rectangle 1 and 3 to 40% width and Rectangle 2 to 20%.
What is wrong in my code?
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Center" Orientation="Vertical" Margin="0,100,0,0">
<StackPanel HorizontalAlignment="Stretch" Orientation="Horizontal">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Height="200" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Beige" StrokeThickness="2" Stroke="Red" />
<Rectangle Grid.Column="1" Height="200" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Rectangle Grid.Column="2" Height="200" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Beige" StrokeThickness="2" Stroke="Red" />
</Grid>
</StackPanel>
</StackPanel>
</Grid>
Why would you need stackpanels at all? You could do with just grids.
Anyway, StackPanel doesn't stretch along its orientation (i.e. vertical stackpanel does not stretch vertically and horizontal stackpanel does not stretch horizontally).
Example:
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="1*"/>
</Grid.ColumnDefinitions>
<Grid
Grid.Row="1"
Grid.Column="1"
Margin="0,100,0,0"
Background="Aquamarine"
>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="3*"/>
<ColumnDefinition Width="4*"/>
<ColumnDefinition Width="3*"/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Height="200" Fill="Beige" StrokeThickness="2" Stroke="Red" />
<Rectangle Grid.Column="1" Height="200"/>
<Rectangle Grid.Column="2" Height="200" Fill="Beige" StrokeThickness="2" Stroke="Red" />
</Grid>
</Grid>
Note: you don't need HorizontalAlignment="Stretch" VerticalAlignment="Stretch" for rectangles -- thay are stretching by default. And specifying VerticalAlignment="Stretch" along with Height="200" doesn't make sense anyway.
Update: And the problem in your inital code is here:
<StackPanel Orientation="Vertical" ... >
<StackPanel Orientation="Horizontal" ...>
<Grid>
Grid tries to occupy all available space. What space is available? You have two nested stackpanels: one doesn't stretch vertically and another doesn't stretch horizontally. So, the grid with no Height or Width specified has zero space available. If you remove Height="200" from rectangles, you may see that your grid is zero-sized.

Make a grid to be closer to the top of the page - XAML

I have the following XAML:
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" Grid.Column="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="0*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<PasswordBox HorizontalAlignment="Center" Grid.Row="0" Margin="12" Width="260" Height="32" PlaceholderText="Confirm Password" BorderBrush="#FF755CB0" BorderThickness="1" Opacity="0.9" x:Name="ConfirmPassword"/>
<Button Content="Sign-Up" HorizontalAlignment="Center" Margin="12" Grid.Row="1" Width="260" Height="50" Background="#FF235085" BorderBrush="#FF6749AC" BorderThickness="1" Foreground="White" Opacity="0.9" RequestedTheme="Light" Click="Register_Click"/>
</Grid>
Right now the grid is at the center of the screen, I wabt it to be a little bit higher, I can do it with margin, but I don't want any propery with pixel in my page. Is there any other wahy to do it?
Thanks.
The easiest way to get your grid slightly above the centre without using Margins would be to put it in another Grid.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="1.2*"/>
</Grid.RowDefinitions>
<Grid HorizontalAlignment="Center" VerticalAlignment="Top" Grid.Row="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="0*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<PasswordBox HorizontalAlignment="Center" Grid.Row="0" Margin="12" Width="260" Height="32" PlaceholderText="Confirm Password" BorderBrush="#FF755CB0" BorderThickness="1" Opacity="0.9" x:Name="ConfirmPassword"/>
<Button Content="Sign-Up" HorizontalAlignment="Center" Margin="12" Grid.Row="1" Width="260" Height="50" Background="#FF235085" BorderBrush="#FF6749AC" BorderThickness="1" Foreground="White" Opacity="0.9" RequestedTheme="Light" Click="Register_Click"/>
</Grid>
</Grid>
Note the second RowDefinition
<RowDefinition Height="1.2*"/>
This means the second row will take slightly more of the available space than the first row and you can adjust to meet your needs.

XAML rectangle not expanding

I have a rectangle that is expanding just fine horizontally, but not vertically:
<Grid x:Name="MainDisplay" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Viewbox MinWidth="400" MinHeight="400" x:Name="Scenario4ImageContainer" Stretch="Fill" Grid.Column="0" Grid.Row="0" VerticalAlignment="Stretch">
<Rectangle MinWidth="400" MinHeight="400" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Blue"/>
</Viewbox>
When I set the MinHeight property to 700 it takes up all the screen space, but I want to take up however much room it can get.
Also this outer grid sits inside of this parent grid:
<Grid x:Name="Output" Background="#1D1D1D" Margin="0,2,0,-2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
I've tried out the XAML you posted and the Rectangle is expanding just fine. The only thing limiting it is the outer Grid which defines two rows of equal height. Try making the second row narrower and you'll see the Rectangle expand:
<Grid x:Name="Output" Background="#1D1D1D" Margin="0,2,0,-2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="300"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Grid x:Name="MainDisplay" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Grid.Column="0" Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="10" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="10" />
</Grid.RowDefinitions>
<Viewbox MinWidth="400" MinHeight="400" x:Name="Scenario4ImageContainer" Stretch="Fill" Grid.Column="0" Grid.Row="0" VerticalAlignment="Stretch">
<Rectangle MinWidth="400" MinHeight="400" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="Blue"/>
</Viewbox>
</Grid>
</Grid>