Detect grid upon grid in XAML - 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));

Related

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

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>

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.

Grid adding unwanted extra vertical space

I have the following xaml inside a user control:
<StackPanel VerticalAlignment="Top">
<Grid Background="LimeGreen">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Grid.Row="0" Grid.RowSpan="3" VerticalAlignment="Top" Fill="Yellow" Width="80" Height="80" />
<Rectangle Grid.Column="1" Grid.Row="0" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Column="1" Grid.Row="1" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Column="1" Grid.Row="2" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
</Grid>
</StackPanel>
and it produces the following layout:
For some reason, this is adding extra unwanted space after the yellow square. I want the following layout instead:
The extra space only occurs when the green grid is inside a stack panel. I can get the correct layout by either:
Putting the green grid inside a grid instead of a stack panel.
Or setting the width of the second column to "Auto". This is undesired, though.
My questions are:
Is the layout in the first picture correct/expected? If so, why is it adding the extra space?
Why does setting the width of the second column to "Auto" get rid of the extra vertical space?
How can I get layout #2 inside a stack panel with width of second column set to * (star)?
I can answer question 3 with this alternative xaml, however it uses a nested grid to bypass using a row span for the yellow square. Ideally this should be possible using just one grid. Anyway, here's the xaml:
<StackPanel VerticalAlignment="Top">
<Grid Background="LimeGreen">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Rectangle VerticalAlignment="Top" Fill="Yellow" Width="80" Height="80" />
<Grid Grid.Column="1">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Rectangle Grid.Row="0" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Row="1" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
<Rectangle Grid.Row="2" VerticalAlignment="Top" Fill="Red" Width="10" Height="10" />
</Grid>
</Grid>
</StackPanel>
I'm still stumped on answering questions 1 and 2.

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>

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