How to put those 3 buttons on the center of bottom? - xaml

In UWP xaml design as below, I split the whole screen to 3 columns and 3 rows. And For row 2 column 1, I need to put a canvas which contains a RelativePanel inside of it. And there will some buttons inside of the panel. My purpose is to make an animation on the panel.
I hope to put those 3 buttons on the bottom/center of the screen, but failed. My layout picture is attached, but it is not what I want.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="10*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="2*" />
<RowDefinition Height="15*" />
<RowDefinition Height="3*"/>
</Grid.RowDefinitions>
<Canvas x:Name="toolbarCanvas" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Center">
<RelativePanel x:Name="toolbarPanel">
<Button x:Name="bt1" Margin="50,0,50,0" Height="100" Width="100" VerticalAlignment="Center" RelativePanel.LeftOf="bt2"/>
<Button x:Name="bt2" Margin="50,0,50,0" Height="100" Width="100" VerticalAlignment="Center" RelativePanel.AlignHorizontalCenterWithPanel="True"/>
<Button x:Name="bt3" Margin="50,0,50,0" Height="100" Width="100" VerticalAlignment="Center" RelativePanel.RightOf="bt2" />
</RelativePanel>
</Canvas>
</Grid>

How to put those 3 buttons on the center of bottom?
Canvas is a layout panel that supports absolute positioning of child elements relative to the top left corner of the canvas.
<Canvas Width="640" Height="480" >
<Rectangle Canvas.Left="30" Canvas.Top="30"
Fill="Red" Width="200" Height="200" />
</Canvas>
For your requirement. Please use Grid panel to replace Canvas and set toolbarPanel VerticalAlignment HorizontalAlignment property like the follow.
<Grid x:Name="toolbarGrid" Grid.Row="2" Grid.Column="0" Grid.ColumnSpan="3" HorizontalAlignment="Center">
<RelativePanel x:Name="toolbarPanel" VerticalAlignment="Bottom" HorizontalAlignment="Center">
<Button x:Name="bt1" Margin="50,0,50,0" Height="100" Width="100" VerticalAlignment="Center" RelativePanel.LeftOf="bt2"/>
<Button x:Name="bt2" Margin="50,0,50,0" Height="100" Width="100" VerticalAlignment="Center" RelativePanel.AlignHorizontalCenterWithPanel="True"/>
<Button x:Name="bt3" Margin="50,0,50,0" Height="100" Width="100" VerticalAlignment="Center" RelativePanel.RightOf="bt2" />
</RelativePanel>
</Grid>

Related

Creating responsive element in XAML

I am absolutely new in UWP and its responsive design, so I need help.
Where's the problem?
e.g. I need 4 responsive buttons on landing page, but in each view it looks quite the same. So the button doesn't change, but looks same on desktop, and same on the phone emulator (or when I change screen resolution). For better description, there are some screens:
Buttons on large 23" screen - looks good, but...
..buttons on small 5" screen (portrait) - buttons are larger then canvas...
So my question is: How to make buttons responsive?
Here is my sourcecode:
<Page
x:Class="STCApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:STCApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="83*"/>
<RowDefinition Height="998*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Button x:Name="button" Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Height="83" Width="480" Background="#33DCFF00"></Button>
<Button x:Name="button_Copy" Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Height="83" Width="480" Grid.Column="1" Background="#33FF0000"/>
<Button x:Name="button_Copy1" Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Height="83" Width="480" Grid.Column="2" Background="#3300FF0C"/>
<Button x:Name="button_Copy2" Content="Button" HorizontalAlignment="Center" VerticalAlignment="Center" Height="83" Width="480" Grid.Column="3" Background="#330080FF"/>
</Grid>
</Page>
For responsive design, we'd better avoid using fixed width and height. We can remove Width and Height setting in Button and set it's HorizontalAlignment and VerticalAlignment to Stretch like following to make the button responsive.
<Button x:Name="button" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#33DCFF00" Content="Button" />
In this scenario, each button will occupy a cell in the grid and their width and height will change automatically according to the size of the gird. Following is a complete sample and for more info about the layout design, please see Layout for UWP apps.
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid.RowDefinitions>
<RowDefinition Height="83*" />
<RowDefinition Height="998*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Button x:Name="button" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#33DCFF00" Content="Button" />
<Button x:Name="button_Copy" Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#33FF0000" Content="Button" />
<Button x:Name="button_Copy1" Grid.Column="2" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#3300FF0C" Content="Button" />
<Button x:Name="button_Copy2" Grid.Column="3" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="#330080FF" Content="Button" />
</Grid>
In this case it's better for you to use a RelativePanel which you can handle with Visual States that will change according to the available screen size. This might help
Windows 10 RelativePanel Sample

How to use full width of Phone in xaml?

I have 3 controls in a Grid.Row but how can I make them use the full width of the page?
This is my xaml:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="140" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Grid.Row="1"
Source="/Assets/image1.png"
Height="25"
Width="25" />
<TextBox Grid.Column="1"
Margin="10,0,0,0"
Text="{Binding InputText, Mode=TwoWay}"
BorderBrush="Black"
BorderThickness="2"
VerticalAlignment="Center">
</TextBox>
<Button Grid.Column="2"
BorderThickness="2"
HorizontalAlignment="Right"
Command="{Binding AddTextCommand}"
Margin="10,0,0,0">
<TextBlock x:Uid="ButtonText" />
</Button>
</Grid>
This is now the result:
As you can see it is aligned left, how can I make it use the full width?
You're code only shows 3 controls (Image, TextBox, Button), while your screenshot gives 4 controls. I suppose the full width control on top is missing, but that's no problem to answer the question.
If we break down your XAML, you have:
First column width Auto, filled with an image.
Second column width 140, filled with a TextBox
Third column width * (or the rest of the space), filled with a Button
On the button you have placed HorizontalAlignment="Right" (default is Left), in which you're saying: only use the space necessary and put the control on the right side. If you want to use the full width available, you have to use HorizontalAlignment="Stretch".
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="140" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Grid.Column="0"
Source="/Assets/image1.png"
Height="25"
Width="25" />
<TextBox Grid.Column="1"
Margin="10,0,0,0"
Text="{Binding InputText, Mode=TwoWay}"
BorderBrush="Black"
BorderThickness="2"
VerticalAlignment="Center">
</TextBox>
<Button Grid.Column="2" x:Uid="ButtonText"
BorderThickness="2"
HorizontalAlignment="Stretch"
Command="{Binding AddTextCommand}"
Margin="10,0,0,0" />
</Grid>
Note that I have also removed the TextBlock from the Button and move the x:Uid tag to the button. Simply use ButtonText.Content in your resources to have your button localized, there's no need to place a TextBlock in there.

Disable opacity on Textblock when grid's opacity is set for WP8

I've posted a similar question in the past but never quite resolved it and so here I am again.
In my layout grid, I have an image which takes the full area but I also display another grid which is vertically aligned to the bottom, has its background color set and its opacity set to .5.
This part works fine.
Now, I want to display another grid within that grid which will contain another image (a logo) and a TextBlock which contains a description.
My problem is that both the image and textblock are being dimmed. While I have no problem with the logo being dimmed, I do want to keep my description fully opaque but can't seem to be able to do this.
Is there a way to achieve this? Note I'm trying to build a custom tile for WP8.
Here is the code:
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image Stretch="UniformToFill" Source="/Assets/0.jpeg" ></Image>
<Grid Background="#0F558E" Opacity="0.5" Visibility="Visible" Height="100" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="/Assets/Tiles/FlipCycleTileSmall.png" Width="100" Height="100" Grid.Column="0" Opacity="1" ></Image>
<TextBlock Foreground="White" FontSize="30" Text="This is a simple description of the article" TextWrapping="Wrap" Margin="10,0,30,0" Grid.Column="1" Opacity="1" />
</Grid>
</Grid>
Thanks.
As you found out, everything that is a child of that grid is going to have a 0.5 opacity, and any opacity settings on the children are going to be relative to that.
Could you just overlay a third grid on top of the second that has the same sizing and contains your image and text? I don't have anything in front of me to test this at the moment, but something like:
<Grid x:Name="LayoutRoot" Background="{StaticResource PhoneChromeBrush}">
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Image Stretch="UniformToFill" Source="/Assets/0.jpeg" ></Image>
<Grid Background="#0F558E" Opacity="0.5" Visibility="Visible" Height="100" VerticalAlignment="Bottom">
</Grid>
<Grid Visibility="Visible" Height="100" VerticalAlignment="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Source="/Assets/Tiles/FlipCycleTileSmall.png" Width="100" Height="100" Grid.Column="0" Opacity="1" ></Image>
<TextBlock Foreground="White" FontSize="30" Text="This is a simple description of the article" TextWrapping="Wrap" Margin="10,0,30,0" Grid.Column="1" Opacity="1" />
</Grid>
</Grid>

Detect grid upon grid in XAML

I have 2 Grids in XAML. One small and one big. How I can detect that, after first move, it upon second? I need smth like coordinates (need to align the first grid to the second grid's border or to other grids in this 'big-grid'). What're methods, properties?
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Grid HorizontalAlignment="Center" VerticalAlignment="Center" x:Name="Parent" Margin="124,340,1042,228">
<Grid.RowDefinitions>
<RowDefinition Height="100"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" ManipulationDelta="Object_ManipulationDelta" x:Name="Figure" ManipulationMode="All">
<Rectangle Fill="Red" Width="40" Height="40"/>
<Rectangle Fill="Red" Width="40" Height="40" Margin="-10,30,70,30"/>
<Rectangle Fill="Red" Width="40" Height="40" Margin="-10,70,70,-10"/>
<Rectangle Fill="Red" Width="40" Height="40" Margin="-50,70,110,-10"/>
<Grid.RenderTransform>
<CompositeTransform/>
</Grid.RenderTransform>
</Grid>
</Grid>
<Grid x:Name="Field" Width="500" Height="700">
<Rectangle Fill="Black" Width="40" Height="40" Margin="10,10,450,650" StrokeThickness="1" Stroke="#FF1B1B1B"/>
<Rectangle Fill="Black" Width="40" Height="40" Margin="50,10,410,650" StrokeThickness="1" Stroke="#FF1B1B1B"/>
<Rectangle Fill="Black" Width="40" Height="40" Margin="90,10,370,650" StrokeThickness="1" Stroke="#FF1B1B1B"/>
<!--many rectangles-->
</Grid>
</Grid>
I move Grid Figure to Grid Field. In future I may be change rectangle to border.
To detect the relative position between Figure and Field, you can use something like that:
var transform= Field.TransformToVisual(Figure);
Point relativePosition = transform.TransformPoint(new Point(0,0));
relativeCoordinate will be the distance between the Top Left of Field and the Top left of Figure
if you want the absolute coordinate of the Grid you can do this:
var transform= this.TransformToVisual(Figure);
Point absolutePositionFigureGrid = transform.TransformPoint(new Point(0,0));

Why doesn't the grid layout work without specifying RowDefinitions and Column Definitions?

<Page
x:Class="AllControls.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:AllControls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d">
<Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
<Rectangle Width="100" Height="100" Fill="Red" Grid.Column="0" Grid.Row="0"/>
<Rectangle Width="100" Height="100" Fill="Orange" Grid.Column="1" Grid.Row="0"/>
<Rectangle Width="100" Height="100" Fill="Yellow" Grid.Column="0" Grid.Row="1"/>
<Rectangle Width="100" Height="100" Fill="Green" Grid.Column="1" Grid.Row="1"/>
<Rectangle Width="100" Height="100" Fill="Blue" Grid.Column="0" Grid.Row="2"/>
<Rectangle Width="100" Height="100" Fill="Indigo" Grid.Column="1" Grid.Row="2"/>
<Rectangle Width="100" Height="100" Fill="Violet" Grid.Column="0" Grid.Row="3"/>
<Rectangle Width="100" Height="100" Fill="Purple" Grid.Column="1" Grid.Row="3"/>
</Grid>
</Page>
I am providing, Row Number and Column number for each element in this case Rectangles. I have also provided height and width for each of them.
I come from an HTML background.
Can someone explain to me how the tags RowDefinitions and ColumnDefinitions work here ?
You have to specify RowDefinitions and ColumnDefinitions so that it knows how to size the rows and columns. Otherwise it doesn't know whether you want auto-sizing or star-sizing. And it also needs to know how many rows and columns you need up front; it doesn't add them on the fly based on your values of Grid.Row and Grid.Column.
I think the code you wrote looks reasonable, and it would be nice if it used a default when you don't specify, but unfortunately it doesn't. Instead, it builds a single-column, single-row grid and stacks all the children on top of each other.
I can think of a couple ways to write some XAML that will do what you want.
One way:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Rectangle Width="100" Height="100" Fill="Red" Grid.Column="0" Grid.Row="0"/>
<Rectangle Width="100" Height="100" Fill="Orange" Grid.Column="1" Grid.Row="0"/>
...
</Grid>
Another way:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="100" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
<RowDefinition Height="100" />
</Grid.RowDefinitions>
<Rectangle Fill="Red" Grid.Column="0" Grid.Row="0"/>
<Rectangle Fill="Orange" Grid.Column="1" Grid.Row="0"/>
...
</Grid>
Like Mr. Andrew pointed out, you'll have to define your layout more to accomplish it using specified RowDefinition / ColumnDefinition to basically manually lay your stuff out. If you're looking for something a bit more fluid with less requirement for defining your layout structure you should look into GridView / VariableSizeWrapGrid (I think is more of what you're looking for.)
Both of which have multiple examples available around the web and are pretty simple to get used to. Hope this helps on your transition from HTML to XAML (ps, in my opinion XAML > HTML)
:)