Align TextBlocks in a circle UWP - xaml

I want to align 12 TextBlocks in a circle like this
InOrder to achieve this I have tried something like this
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
<RowDefinition Height="24"></RowDefinition>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24"></ColumnDefinition>
<ColumnDefinition Width="24"></ColumnDefinition>
<ColumnDefinition Width="24"></ColumnDefinition>
<ColumnDefinition Width="24"></ColumnDefinition>
<ColumnDefinition Width="24"></ColumnDefinition>
<ColumnDefinition Width="24"></ColumnDefinition>
<ColumnDefinition Width="24"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="9" Grid.Column="0" Grid.Row="3"></TextBlock>
<TextBlock Text="10" Grid.Column="1" Grid.Row="2"></TextBlock>
<TextBlock Text="11" Grid.Column="2" Grid.Row="1"></TextBlock>
<TextBlock Text="12" Grid.Column="3" Grid.Row="0"></TextBlock>
<TextBlock Text="1" Grid.Column="4" Grid.Row="1"></TextBlock>
<TextBlock Text="2" Grid.Column="5" Grid.Row="2"></TextBlock>
<TextBlock Text="3" Grid.Column="6" Grid.Row="3"></TextBlock>
<TextBlock Text="4" Grid.Column="5" Grid.Row="4"></TextBlock>
<TextBlock Text="5" Grid.Column="4" Grid.Row="5"></TextBlock>
<TextBlock Text="6" Grid.Column="3" Grid.Row="6"></TextBlock>
</Grid>
But this doesn't give me a good circle, is there any other way to achieve label arranged in a circle?

If you want to create a good circle, the grid is not a suitable solution. Using a coordinate system in canvas might be a way to create a good circle. Let's say we need a clock whose size is 200*200. So the center point (x0,y0) is (100,100). As we know, the angle between the two adjacent numbers is 30. Then the center point of the TextBlock for 2 o'clock- (x2, y2) can be calculated.
x2 = x0 + r * cos(Math.PI * angle/ 180.0) and y2 = y0 - r * sin(Math.PI * angle/ 180.0)
It's the same for other TextBlocks.
Updated
I made a simple sample for this.
Xaml:
<Canvas Background="Gray" Width="300" Height="300" >
<TextBlock Text="2" x:Name="textblock2" ></TextBlock>
<TextBlock Text="1" x:Name="textblock1" ></TextBlock>
<TextBlock Width="20" Height="20" Text="12" Canvas.Top="40" Canvas.Left="140"></TextBlock>
<TextBlock Width="20" Height="20" Text="9" Canvas.Top="140" Canvas.Left="40"></TextBlock>
<TextBlock Width="20" Height="20" Text="3" Canvas.Top="140" Canvas.Left="240" ></TextBlock>
<TextBlock Width="20" Height="20" Text="6" Canvas.Top="240" Canvas.Left="140" ></TextBlock>
</Canvas>
Code behind:
int r = 100;
//1 o'clock
// need to minus 10 to get Canvas.top and Canvas.lelf value because x1 y1 represent the center of the textblock not the center of the textblock
double x1 = 150 + r * Math.Cos(Math.PI * 60 / 180.0) - 10;
double y1 = 150 - r * Math.Sin(Math.PI * 60 / 180.0) - 10;
textblock1.SetValue(Canvas.LeftProperty, x1);
textblock1.SetValue(Canvas.TopProperty, y1);
//2 o'clock
double x2 = 150 + r * Math.Cos(Math.PI * 30 / 180.0)-10;
double y2 = 150 - r * Math.Sin(Math.PI * 30 / 180.0)-10;
textblock2.SetValue(Canvas.LeftProperty, x2);
textblock2.SetValue(Canvas.TopProperty, y2);
What it looks like:

Related

How to disable scaling for UWP apps

I'm designing uwp apps. My pc resolution is 1920 x 1080, 100% scale. All the elements are layout normal.
But when running app on a screen 1920 x 1080, 125% scale, the elements are not in the right place and all are 1.25x bigger.
So how to disable scale under all resolutions, or is there any solutions?
I am giving you the simple example in which i am showing two buttons and one grid you can run this on any resolution the left and right hand side button always keep in same position and grid will change accordingly resolution size
<Grid HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" >
<Grid.RowDefinitions>
<RowDefinition Height="150"/>
<RowDefinition Height="169*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="150"/>
<ColumnDefinition Width="113*"/>
<ColumnDefinition Width="150"/>
</Grid.ColumnDefinitions>
<Button Content="Button" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,55,10,40" />
<Button Content="Button" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Margin="10,55,10,40" Grid.Column="2" />
<Grid Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" BorderBrush="Black" BorderThickness="2" Grid.RowSpan="2"/>
</Gid>
your code sample
<Grid HorizontalAlignment="Stretch" Margin="0,0,0,0" VerticalAlignment="Stretch" >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="945"/>
<ColumnDefinition Width="945"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Color"
Margin="117, 84, 0, 0"
FontSize="48"/>
<Button Grid.Row="1" Content="Red" Width="500" Height="80" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
Margin="445 30 0 0"
/>
<Button Grid.Row="1" Grid.Column="1" Content="Yellow" Width="500" Height="80"
Margin="0 30 445 0"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
<Grid Grid.Row="2" Grid.ColumnSpan="2"
Margin="84 40 84 0" HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" BorderBrush="Black" BorderThickness="2"/>
</Grid>

UWP TextBox won't stretch in StackPanel

I have a TextBlock and TextBox controls inside StackPanel, and I need to stretch TextBox to resize by the parent size in UWP.
<StackPanel Grid.Column="0" Grid.Row="1" Orientation="Horizontal">
<TextBlock Text="Name:" VerticalAlignment="Center" Width="130" />
<TextBox VerticalAlignment="Center" HorizontalAlignment="Stretch" />
</StackPanel>
This not works.. Any ideas?
The problem is the stack panel will only stretch to the size of the child elements so in your example you will only see one Textblock of 130 pixels and you will not see the TextBox.
To get the functionality you desire you should use a grid with two columns one 130 pixels and the other being * to fill up the entire column space that is available.
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="130"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Grid.Column="0" Text="Name:" VerticalAlignment="Center" Width="130" />
<TextBox Grid.Row="0" Grid.Column="1"/>
</Grid>
I usually wrap a TextBlock and TextBox pair inside a DockPanel
<DockPanel Grid.Column="0" Grid.Row="1" >
<TextBlock Text="Name:"
VerticalAlignment="Center"
Margin="5"
/>
<TextBox VerticalAlignment="Center"/>
</DockPanel>
Edit
For UWP which doesn't have DockPanel:
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid Grid.Column="0" Grid.Row="1" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition />
</Grid.ColumnDefinitions>
<TextBlock Text="Name:"
VerticalAlignment="Center"
Margin="5"
/>
<TextBox Grid.Column="1"
VerticalAlignment="Center" HorizontalAlignment="Stretch" />
</Grid>
</Grid>
I worked out a similar problem in UWP
<StackPanel Margin="{StaticResource SmallTopBottomMargin}" Orientation="Vertical">
<TextBlock Text="Project Name:" />
<TextBox /> <--full width
<TextBlock Text="Exported Template:" /> <--full width
<Grid HorizontalAlignment="Stretch">
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition Width="auto"/>
</Grid.ColumnDefinitions>
<TextBox /> <--max width - button width
<Button Grid.Column="1">...</Button>
</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.

xaml Grid outlining

First I want to let you know that I am not really into all of the XAML features. I am creating one of my first applications in the Windows 8 .Xaml area.
Right now I'm creating a legend in which all the points that can be found in the application are explained.
For this legend I am using the Grid defenitions to define the rows and columns that are being displayed.
My question is, does someone know how to outline the defined rows and columns in the grid?
(Some of the code I used to create the legend:
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="lText1" Grid.Column="1" Grid.Row="0" Text="Definition 1" FontSize="33"/>
<TextBlock x:Name="lText2" Grid.Column="1" Grid.Row="1" Text="Definition 2" FontSize="33"/>
<TextBlock x:Name="lText3" Grid.Column="1" Grid.Row="2" Text="Definition 3" FontSize="33"/>
<TextBlock x:Name="lText4" Grid.Column="1" Grid.Row="3" Text="Definition 4" FontSize="33"/>
<TextBlock x:Name="lText5" Grid.Column="1" Grid.Row="4" Text="Definition 5" FontSize="33"/>
)
The easiest way is to set ShowGridLines property of your Grid to True
ShowGridLines="True"
There are other options, depending on how you want the outlines be displayed exactly. Some of those options are explained in this SO post.
UPDATE :
Since you develop on Win RT platform which doesn't have ShowGridLines property, you should make outlines on your own. The minimum effort I can think is to add Rectangle for each Row spanning through all columns, and add Rectangle for each column spanning through all rows. That way will need less Rectangles than if you create it for each cell as shown in above link. Check this other SO post for example. And example for your case :
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"/>
<ColumnDefinition Width="7*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
<RowDefinition Height="1*"/>
</Grid.RowDefinitions>
<TextBlock x:Name="lText1" Grid.Column="1" Grid.Row="0" Text="Definition 1" FontSize="33"/>
<TextBlock x:Name="lText2" Grid.Column="1" Grid.Row="1" Text="Definition 2" FontSize="33"/>
<TextBlock x:Name="lText3" Grid.Column="1" Grid.Row="2" Text="Definition 3" FontSize="33"/>
<TextBlock x:Name="lText4" Grid.Column="1" Grid.Row="3" Text="Definition 4" FontSize="33"/>
<TextBlock x:Name="lText5" Grid.Column="1" Grid.Row="4" Text="Definition 5" FontSize="33"/>
<!-- Horizontal Lines -->
<Rectangle Grid.ColumnSpan="2" Height="1" VerticalAlignment="Bottom" Fill="Black"/>
<Rectangle Grid.Row="1" Grid.ColumnSpan="2" Height="1" VerticalAlignment="Bottom" Fill="Black"/>
<Rectangle Grid.Row="2" Grid.ColumnSpan="2" Height="1" VerticalAlignment="Bottom" Fill="Black"/>
<Rectangle Grid.Row="3" Grid.ColumnSpan="2" Height="1" VerticalAlignment="Bottom" Fill="Black"/>
<Rectangle Grid.Row="4" Grid.ColumnSpan="2" Height="1" VerticalAlignment="Bottom" Fill="Black"/>
<!-- Vertical Lines -->
<Rectangle Grid.RowSpan="5" Width="1" HorizontalAlignment="Right" Fill="Black"/>
<Rectangle Grid.Column="1" Grid.RowSpan="5" Width="1" HorizontalAlignment="Right" Fill="Black"/>
Just add ShowGridLines="True" to your grid
For example
<Grid Name="grdValues" Height="155" ShowGridLines="True">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="125"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="75"/>
<RowDefinition Height="75"/>
</Grid.RowDefinitions>
</Grid>
Update
<Border BorderThickness="1" Grid.Column="1" Grid.Row="0" Name="brdUsrName" HorizontalAlignment="Stretch" VerticalAlignment="Center" Height="60" Background="Black">
<TextBlock x:Name="lText1" Text="Definition 1" FontSize="33"/>
</Border>

Width of controls inside listbox not changing after orientation change

I have a grid inside stackpanel which is inside a listbox.
This grid has a few control elements like rectangles and textblocks.
They stretch to the entire width in portrait but not in landscape.
Snapshot of emulator
This is the XAML:
<ListBox Name="PassList" VerticalAlignment="Stretch" HorizontalAlignment="Stretch">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel HorizontalAlignment="Stretch">
<Grid Name="StackPanelWidth" Width="{Binding ElementName=PassList, Path=ActualWidth}">
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="20"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="{Binding ElementName=StackPanelWidth, Path=ActualWidth}"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
<Rectangle Fill="White"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
RadiusX="10"
RadiusY="10"
/>
<Rectangle Fill="White"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Margin="0,10,0,0"
/>
<Rectangle Fill="DarkGray"
Grid.Row="0"
Grid.Column="1"
Height="1"
VerticalAlignment="Bottom"
/>
<TextBlock Name="Country"
Grid.Row="0"
Grid.Column="1"
HorizontalAlignment="Left"
Margin="10,0,0,0"
VerticalAlignment="Center"
Text="{Binding Country}"
Foreground="Black"
FontWeight="Bold"
/>
.............
.............
</Grid>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Is there any thing wrong with my code?
Any help will be appreciated.
Thanks.
why are you doing this?
<Grid.ColumnDefinitions>
<ColumnDefinition Width="10"/>
<ColumnDefinition Width="{Binding ElementName=StackPanelWidth, Path=ActualWidth}"/>
<ColumnDefinition Width="10"/>
</Grid.ColumnDefinitions>
Here you are somehow specifying the width because of which its not resizing.
Also the stackpanel will automatically adjust to its child width, so no need to specify binding if thats what you were trying to do.