Scaling doesn't work in the 23 and 27 inch screens - xaml

I have two UserControls that have a Grid each. The first one defines a Height and a Width:
<UserControl
Height="620"
Width="450">
<Grid Margin="50, 0, 0, 50">
The other control only defines the Height:
<UserControl
Height="768">
<Grid>
Now I am trying to use both in a background like this:
<Grid>
<Image Source="Assets/background.png" Stretch ="UniformToFill"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Controls:EventImagesControl Grid.Row="0" Grid.Column="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
<Controls:ScrollControl Grid.Row="0" Grid.Column="1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"/>
</Grid>
</Grid>
Everything scales as I was expecting in the following settings:
10.6" 1024x768
10.6" 1366x768
10.6" 1920x1080
10.6" 2560x1440
12" 1280x800
However, when I try to use the following settings it only scales in width and not in height (at least it seems)
23" 1920x1080
27" 2560x1440
I am trying to avoid the usage of a ViewBox. I am new to the windows8/wpf, but I am trying to learn how to do a responsive layout.

The WinRT rendering engine scales so everything is physically correct, that's why the 4 10.6" tests look the same size, no matter the resolution of the screen. The 12" test scales nicely, but as it's size is close to the 10.6" and you won't notice a difference (althought there's a difference), the biggest screen sizes will scale so your 450x620 control look like a 450x620 control an a 23" Full HD screen, this means an small control.
Actually, the link you posted describes nicely every type of scaling you can use in a Modern UI app. And if you really need to set a minimum size, use the MinWidth and MinHeight properties instead.

Related

UWP XAML: How to get an auto-sized Grid with equal column widths

My goal is to have a Grid panel that has two columns of controls (each column will contain a vertical StackPanel), where both columns are the same width but auto-sized based on the controls they contain. So both column widths will be equal to the widest control in either column.
I tried doing something like this:
<Grid HorizontalAlignment="Center">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0" Content="This is a wide button" HorizontalAlignment="Center" />
<Button Grid.Column="1" Content="Button" HorizontalAlignment="Center" />
</Grid>
The problem here is that the column widths aren't equal. The effect is the same as if I would have specified Width="Auto" for the column definitions. Using a * width only makes the columns equal width if the grid has a HorizontalAlignment of Stretch instead of Center. (Except then the columns aren't auto-sized to the content anymore.)
Am I missing something? Is there a way to get equal-sized column widths based on the content in the grid cells? In a UWP app (so things like UniformGrid aren't available)?
Thats because you have set HorizontalAlignment to "Center" , Grid wont occupy complete page just occupies center part(its horizontal space depends on sum of child elements, in this case it wont add up to fill up whole page.
Just change the HorizontalAlignment = "Stretch" so that whole space available and individual grid components occupy half space.
<Grid HorizontalAlignment="Stretch" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Button Grid.Column="0"
Content="This is a wide button"
HorizontalAlignment="Center" />
<Button Grid.Column="1"
Content="Button"
HorizontalAlignment="Center"/>
</Grid>
Image:
The Windows Community Toolkit has a Uniform Grid control you can use if you add in the NuGet package.
Telerik RadDataGrid control will help you with your scenario
Add\install Telerik.UI.Xaml.Controls.Grid from Nuget inorder to use RadDataGrid in your UWP App

How to use MaxWidth instead of Width

I have question about MaxWidth. Lets look at this code:
<Grid Height="50" Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Width="200" Background="Green" BorderBrush="Black" BorderThickness="2" />
<Grid Grid.Column="2" Width="200" Background="Yellow" BorderBrush="Black" BorderThickness="2" />
<Grid Grid.Column="3" Width="200" Background="Blue" BorderBrush="Black" BorderThickness="2" />
</Grid>
We have red Grid with height 50px and width whole screen. In this grid i want to have 3 items, for example grids, one left of screen and two right of screen, all with width 200px.
On bigger screens this code works good, we have green 200px grid on left, and two yellow and blue 200px grids on right, with red space between them.
But on smaller screens(smaller than 600px) blue grid is cut off. I want to green and yellow grids stay 200px, and blue grid to take as much as it can, for example 150px or 100px. I try to just change Width=200 to MaxWidth=200 on blue grid, but with this code blue grid disappear. It is not stretching, its width is 0. How to make it stretching as much as possible, up to 200px?
You can achieve the desired effect with this XAML:
<Grid Height="50" Background="Red">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="999*" MaxWidth="200" />
</Grid.ColumnDefinitions>
<Grid Grid.Column="0" Width="200" Background="Green" BorderBrush="Black" BorderThickness="2" />
<Grid Grid.Column="2" Width="200" Background="Yellow" BorderBrush="Black" BorderThickness="2" />
<Grid Grid.Column="3" Background="Blue" BorderBrush="Black" BorderThickness="2" >
<Button HorizontalAlignment="Right" Content="Test"/>
</Grid>
</Grid>
I've added a Button in the Blue Grid to show that it stretches correctly.
The trick is to set the MaxWidth on the ColumnDefinition level and remove the 200px restriction at the Grid level (otherwise it will never get smaller than that).
The 'hack' comes at the Width of the ColumnDefinition where you need to allow it to stretch freely, which is achieved with '*'. But you already have a stretchable column. So you need to have the 2nd column (the Red one) shrink first and only then start shrinking the Blue one. While this is not possible out of the box, you can use this trick to achieve it. 999* means that the Blue column should be 999 times larger than the red one so when you resize it will try to maintain that ratio. Only when the Red one becomes small enough (0px at this point) will the blue one start to resize.

Prevent Image from stretching beyond actual size

I have an Image control bound to a source. Here is what I want:
If the source image is smaller than the Grid containing it, it should display at its original size. It should not stretch beyond 100%. This is behavior of setting Stretch="None".
If the source image is larger than parent Grid, it should be resized uniformly to fit the container. This behavior is available with Stretch="Uniform".
I have tried to bind MaxWidth and MaxHeight to parent's actual dimensions as follows:
<DataTemplate x:Key="ImageDataTemplate">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Title}" Grid.Row="0"/>
<TextBlock Text="{Binding Type}" Grid.Row="1"/>
<Grid x:Name="ImageWrapper" Grid.Row="1" Tapped="ImageWrapper_Tapped" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Background="AliceBlue">
<Image Source="{Binding Link}" MaxWidth="{Binding ActualWidth, ElementName=ImageWrapper}" MaxHeight="{Binding ElementName=ImageWrapper, Path=ActualHeight}"/>
</Grid>
</Grid>
</DataTemplate>
However, I just end up with no image at all. Parent Grid occupies all available space as can be seen from background color. But there's no image.
Is there a way to achieve behavior I want?
Put the Image in a Viewbox control and set the Viewbox's StretchDirection to DownOnly. The Stretch property of the Viewbox has a default value of Uniform, so you don't need to set it.
<Viewbox StretchDirection="DownOnly">
<Image Source="{Binding Link}" Stretch="None"/>
</Viewbox>
Perhaps worth to note, in WPF you could directly set the StretchDirection of the Image control, and thus would not need a Viewbox.
<Image Source="{Binding Link}" StretchDirection="DownOnly"/>

How Windows Phone StackPanel Child Element share avaiable width

In windows Phone XAML, I have a StackPanel in Horizontal Orientation and I want it's child UI controls to share equal available width equally or in my case, I want TextBlock to share 1/3 and TextBox to get 2/3 of available width. How I can get that without giving hard coded values to width?
Below is the code example.
<StackPanel Orientation="Horizontal">
<TextBlock Text="Bill Total: "
VerticalAlignment="Center"/>
<TextBox InputScope="Number"
VerticalAlignment="Center"
PlaceholderText="Bill Total"
AcceptsReturn="True"
x:Name="txtBillTotal"
/>
</StackPanel>
As far as I can see, you can't do that with StackPanel. Try to use Grid instead with column definitions width set proportionally :
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Bill Total: "
VerticalAlignment="Center"/>
<TextBox Grid.Column="1"
InputScope="Number"
VerticalAlignment="Center"
PlaceholderText="Bill Total"
AcceptsReturn="True"
x:Name="txtBillTotal"
/>
</Grid>
That will set the 2nd column twice wider than the 1st, which means 2/3 Grid width. And the rest 1/3 given to the 1st column.

Transparent Grid in Windows Phone?

I'm trying to write a page for WP8 which plays video, using the MediaElement API.
I am having difficulties in placing the play/pause controls over the video.
I am currently using a grid to house the controls over the video. The problem is that I cannot make the grid transparent. This is the XAML -
<StackPanel Background="Transparent">
<MediaElement Name="media" Source="http://video-js.zencoder.com/oceans-clip.mp4" AutoPlay="True"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<!-- Play button. -->
<!-- Pause button. -->
<Grid Background="Transparent" VerticalAlignment="Bottom" Margin="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".5*"/>
<ColumnDefinition Width=".5*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="85" />
</Grid.RowDefinitions>
<Image Grid.Column="0" Source="Assets\transport.pause.png" Height="79" Width="79"/>
<Image Grid.Column="1" Source="Assets\transport.play.png" Height="79" Width="79"/>
</Grid>
</StackPanel>
I can still see a black portion where the Grid is.
Is there a better way to accomplish this?
You've put the controls in a StackPanel. That means that you'll end up with:
StackPanel
MediaElement
Grid
Button/Image
Button/Image
A StackPanel is designed to stack controls either horizontally or vertically. It is not for overlaying controls. So, the black background you're seeing is the background beneath the Grid, which is likely the default background brush/color of the application (black).
If you instead were to use a Grid to host the controls, you can use an overlay as you need to:
<Grid x:Name="ContentPanel" >
<Grid>
<MediaElement Name="media" Source="Assets/sample_mpeg4.mp4"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch" />
<Grid Background="#80000000" VerticalAlignment="Center" >
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" >Pause</Button>
<Button Grid.Column="1" Click="Button_Click_1" >Play</Button>
</Grid>
</Grid>
</Grid>
It's now:
Grid
MediaElement
Grid
Button
Button
It would look something like this:
Using the Grid, I've put both the MediaElement and the inner Grid in the same cell (by using the default attached property values for Row and Column which are `0').
In the above code, I've used a Grid to layout the MediaElement and another Grid which will layout the two Buttons I've used. In this case, I've centered the Grid with the Buttons so that the buttons appear in the center of the MediaElement.
I've also used a somewhat transparent Background for the Grid which contains the buttons.
I've dealt with this issue before but can't remember exactly how I solved it. I remember researching this, which is using visual media as a Brush to then paint the background of the Grid that houses the buttons. IIRC, the issue is not necessarily with the Grid, it's with anything overlaying the MediaElement. Because of some special drawing procedure involved with the MediaElement it doesn't handle overlays and transparencies well. There is a solution, but like I said I can't completely remember. But try out using the video as a Brush for the background of the Grid.