ContentPresenter's "Content" not centrally aligned vertically in UWP Controls - xaml

I am using a ToggleSwitch control to display 2 exclusive options in the application. Unfortunately, when FontSize increases the "Content" part seems to be not centrally aligned vertically.
To verify the issue I tried with a simple ContentPresenter even though I have provided VerticalAlignment, VerticalContentAlignment, etc.
Not sure if it's an open issue or I am missing something here?
White line shows the center of the image here. This is just one case but as font size differs the alignment also changes. Thus we cannot provide a padding/margin as it is different for various FontSizes.
<Page
x:Class="TestApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:TestApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="Green">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="30">
<ToggleSwitch Background="Red" OnContent="ABRA" OffContent="KADABRA" FontSize="72"/>
<ContentPresenter Background="Red" Content="KADABRA" FontSize="58"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
VerticalAlignment="Center" VerticalContentAlignment="Center" />
</StackPanel>
</Page>
As an update: I also tried modifying the ContentPresenter style as follows and applied it to the above ContentPresenter (still no change though)
<Style x:Key="ContentPresenterStyle1" TargetType="ContentPresenter">
<Setter Property="VerticalAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
</Style>

This issue is caused by the font metrics. Font metrics decide how much space is above the font/below the font and also how much space is between the characters. Different font sizes and font families will have different metrics.
Currently, there is not much we could do with that. Using TranslateTransform or TextBlock with margin is a workaround for this. Another possible way is to use Win2D to draw the text directly but it might be complicated.

Probably not the ideal answer; but you could always use the RenderTransform to adjust it to your liking.
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" VerticalAlignment="Center" Spacing="30" >
<ToggleSwitch Background="Red" >
<ToggleSwitch.OffContent>
<TextBlock Text="KADABRA" FontSize="72" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Y="-5"/>
</TextBlock.RenderTransform>
</TextBlock>
</ToggleSwitch.OffContent>
<ToggleSwitch.OnContent>
<TextBlock Text="KADABRA" FontSize="72" VerticalAlignment="Center">
<TextBlock.RenderTransform>
<TranslateTransform Y="-5"/>
</TextBlock.RenderTransform>
</TextBlock>
</ToggleSwitch.OnContent>
</ToggleSwitch>
</StackPanel>

Related

WP 8.1 bottom to top infinite scrolling

I have explored ISupportIncrementalLoading and seen MS sample and other examples for infinite scrolling behaviour.
But I want bottom to top scrolling where items are added on top on scrolling bottom to top.
Edit:I have found a workaround for this. I have rotated listview by 180 degree and datatemplate by 180 degree which helped me achieve desired functionality.
<ListView x:Name="GridViewMain" IncrementalLoadingThreshold="2" RenderTransformOrigin="0.5,0.5">
<ListView.RenderTransform>
<RotateTransform Angle="180"></RotateTransform>
</ListView.RenderTransform>
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="VerticalContentAlignment" Value="Stretch"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.Resources>
<DataTemplate x:Key="DataTemplateGridViewMain">
<Grid HorizontalAlignment="Stretch" Background="#FF7C1A9B" RenderTransformOrigin="0.5,0.5">
<Grid.RenderTransform>
<RotateTransform Angle="180"/>
</Grid.RenderTransform>
<TextBlock HorizontalAlignment="Left" Text="{Binding}" VerticalAlignment="Center" FontSize="20" FontFamily="Tempus Sans ITC" />
</Grid>
</DataTemplate>
</ListView.Resources>
<ListView.ItemTemplate>
<StaticResource ResourceKey="DataTemplateGridViewMain" />
</ListView.ItemTemplate>
</ListView>
Is this solution has any perf impact or is there any alternate way to do this?
not sure if this will fit your needs, but I had to do something similar when creating a chat conversation screen, and was able to achieve this using ExtendedListView: https://www.nuget.org/packages/ExtendedListView
We load the most recent items, and use ScrollIntoView(lastMessage) to position the cursor at the bottom. Normally you would use MoreDataRequested event to get items when it scrolls to the bottom, but instead we reversed it and used the PullToRefreshRequested to simulate scrolling to the top, changing the loading template to say "loading more messages".
works pretty well for us, I hope this is helpful!

How to remove "focused" border from XAML listbox?

This problem is about the listbox itself and not it's cells. If I put listbox into a viewbox, and click on an item, the whole listbox will be surrounded with a 1px border. I do not want that, because it is ugly. How to remove this border?
Details:
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Viewbox Grid.Row="1" Stretch="Uniform">
<StackPanel Orientation="Horizontal" Margin="0,20,0,20">
<Grid Width="200">
<ListBox ItemsSource="{Binding Rajzelemek}" Background="{x:Null}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ContentControl Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Content="{Binding Ikonja}" Width="25" Height="25" VerticalAlignment="Center" />
<TextBlock Text="{Binding}" VerticalAlignment="Center" Foreground="{ThemeResource ApplicationForegroundThemeBrush}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" />
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
</Grid>
</StackPanel>
</Viewbox>
</Grid>
If I comment the <Viewbox Grid.Row.... part, everything is fine, but not scaled. I want stuff to get scaled, well that is why I use the viewbox, but I do not want this border:
The code above was put on a metro BlankPage1 too, and made the same thing.
I think you're looking for what's in the ListBoxItem template wherein there's a Rectangle acting as a Focus Visual, if you check out the default template you'll see it with a default brush attributed to it (FocusVisualWhiteStrokeThemeBrush) which you could either change in the template, or provide your own resource for it to find before it hits the default dictionaries like;
<SolidColorBrush x:Key="FocusVisualWhiteStrokeThemeBrush" Color="Transparent" />
Hope this helps.
EDIT
Sorry I was going by the picture you have, thought it was the item. In any case since your ViewBox is the culprit you just need to interact with the Border control within it >like you showed in a previous post of your own< where you're the one making that border. Something like;
<Viewbox>
<Viewbox.Resources>
<Style TargetType="Border">
<Setter Property="BorderBrush" Value="Transparent" />
<Setter Property="BorderThickness" Value="0" />
</Style>
</Viewbox.Resources>
...
</ViewBox>

silverlight vertical progressbar

I can not figure out what I did wrong. I have a Usercontrol that has a vertical progressbar and under it a label.
<UserControl x:Class="IFramedInBrowser.Code"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" Height="150" Width="15">
<Grid Width="120" Height="15" >
<StackPanel Width="120" Height="15" >
<ProgressBar Grid.Row="0" Value="{Binding Path=Percent}" Maximum="100" Width="120" Height="15" />
</StackPanel>
<TextBlock Grid.Row="1" Height="30" HorizontalAlignment="Left" Name="textBlock1" Text="{Binding Path=Symbol.Name}" VerticalAlignment="Top" >
<TextBlock.RenderTransform>
<RotateTransform Angle="90"/>
</TextBlock.RenderTransform>
</TextBlock>
<Grid.RenderTransform>
<RotateTransform Angle="-90"/>
</Grid.RenderTransform>
</Grid>
</UserControl>
This usercontrol is then used in a ItemsControl
<ItemsControl x:Name="HorizontalListBox"
ItemsSource="{Binding Source={StaticResource MyViewModel}, Path=List}"
HorizontalAlignment="Stretch"
HorizontalContentAlignment="Center" Height="150"
>
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<my:Code DataContext="{Binding}">
</my:Code>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
It should look like a piano keybord at the end...
After the rotation transformation the progressbar is chopped... What did I dowrong? How to fix this?
You can try to add different background colors to all controls to find out sizes of controls.
Also SilverlightSpy is now free for read only and you can go through the real visual tree at runtime.
Anyway, I would suggest to change the orientation of ProgressBar by customizing its template.
This is a clipping issue. You are setting too many heights and widths everywhere and it's confusing to know which one is in control of dimensions. Also, the stacking in the ListBox works on the layout and the RotateTransform is only effective on the final visual pass, so it's rotating a clipped progress bar.
You should follow jumbo's advice and create a vertical progress bar by modifying the template, not by rotation.
If you don't want to create the template, then you need to remove the main Grid you have in the UserControl and use a Canvas instead. Canvases don't clip. They let your elements float freely, which is probably what you want.

How can I vertically align a TextBox inside a StackPanel?

In the following XAML, the word "Test" centers horizontally but not vertically.
How can I get it to center vertically?
<Window x:Class="TestVerticalAlign2343.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
WindowStartupLocation="CenterScreen"
Title="Window1" Height="768" Width="1024">
<DockPanel LastChildFill="True">
<Slider x:Name="TheSlider"
DockPanel.Dock="Left"
Orientation="Vertical"
HorizontalAlignment="Center"
HorizontalContentAlignment="Center"
Minimum="0"
Maximum="10"
Cursor="Hand"
Value="{Binding CurrentSliderValue}"
IsDirectionReversed="True"
IsSnapToTickEnabled="True"
Margin="10 10 0 10"/>
<Border DockPanel.Dock="Right" Background="Beige"
Padding="10"
Margin="10"
CornerRadius="5">
<StackPanel Height="700">
<TextBlock
Text="Test"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="200" x:Name="TheNumber"/>
</StackPanel>
</Border>
</DockPanel>
</Window>
A stackpanel, no matter how you stretch it, will collapse around the children. you can't make it grow more than that. Basically, that "Height=700" is not helping you.
So either set VerticalAlignment on the StackPanel to "center" so that the stackpanel goes into the center of the dockpanel...or remove the stackpanel altogether and set VerticalAlignment="Center" on the TextBlock.
Seems I asked this question 10 months ago, I got the above scenario to work by replacing the StackPanel with DockPanel LastChildFill=True like this:
<DockPanel LastChildFill="True">
<TextBlock
DockPanel.Dock="Top"
Text="Test"
HorizontalAlignment="Center"
VerticalAlignment="Center"
FontSize="200" x:Name="TheNumber"/>
</DockPanel>
I stumbled across this which seems to work perfectly:
<Grid>
<TextBlock Text="My Centered Text"
TextAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
The Grid ensures that the single TextBox within it fills the solitary cell in the grid and the VerticalAlignment in the TextBlock ensures that the text is centered within than.
Simply position/align your text horizontally however you require (the above snippet centers it in this axis also, but changing this doesn't alter the vertical centering).
Inside the StackPanel that surrounds the TextBlock, check out VerticalContentAlignment.

How to get a ListBox ItemTemplate to stretch horizontally the full width of the ListBox?

I want to have the ListItems to extend with their orange background the full width of the Listbox.
Currently they are only as wide as the FirstName + LastName.
I've set every element I can to: HorizontalAlignment="Stretch".
I want the background of the ListboxItems to expand as the user stretches the Listbox so I don't want to put in absolute values.
What do I have to do so that the background color of the ListBoxItems fill the width of the ListBox?
<Window x:Class="TestListBoxSelectedItemStyle.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:TestListBoxSelectedItemStyle"
Title="Window1" Height="300" Width="300">
<Window.Resources>
<local:CustomerViewModel x:Key="TheDataProvider"/>
<DataTemplate x:Key="CustomerItemTemplate">
<Border CornerRadius="5" Background="Orange" HorizontalAlignment="Stretch" Padding="5" Margin="3">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" Width="Auto">
<TextBlock HorizontalAlignment="Stretch">
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="FirstName"/>
<Binding Path="LastName"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
</StackPanel>
</Border>
</DataTemplate>
</Window.Resources>
<Grid>
<ListBox ItemsSource="{Binding Path=GetAllCustomers, Source={StaticResource TheDataProvider}}"
ItemTemplate="{StaticResource CustomerItemTemplate}"/>
</Grid>
</Window>
I found another solution here, since I ran into both post...
This is from the Myles answer:
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListBox.ItemContainerStyle>
This worked for me.
I'm sure this is a duplicate, but I can't find a question with the same answer.
Add HorizontalContentAlignment="Stretch" to your ListBox. That should do the trick. Just be careful with auto-complete because it is so easy to get HorizontalAlignment by mistake.
If your items are wider than the ListBox, the other answers here won't help: the items in the ItemTemplate remain wider than the ListBox.
The fix that worked for me was to disable the horizontal scrollbar, which, apparently, also tells the container of all those items to remain only as wide as the list box.
Hence the combined fix to get ListBox items that are as wide as the list box, whether they are smaller and need stretching, or wider and need wrapping, is as follows:
<ListBox HorizontalContentAlignment="Stretch"
ScrollViewer.HorizontalScrollBarVisibility="Disabled">
(credits for the scroll bar idea)
Since the border is used just for visual appearance, you could put it into the ListBoxItem's ControlTemplate and modify the properties there. In the ItemTemplate, you could place only the StackPanel and the TextBlock. In this way, the code also remains clean, as in the appearance of the control will be controlled via the ControlTemplate and the data to be shown will be controlled via the DataTemplate.
The fix for me was to set property HorizontalAlignment="Stretch" on ItemsPresenter inside ScrollViewer..
Hope this helps someone...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBox">
<ScrollViewer x:Name="ScrollViewer" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Foreground="{TemplateBinding Foreground}" Padding="{TemplateBinding Padding}" HorizontalAlignment="Stretch">
<ItemsPresenter Height="252" HorizontalAlignment="Stretch"/>
</ScrollViewer>
</ControlTemplate>
</Setter.Value>
</Setter>
I also had the same problem, as a quick workaround, I used blend to determine how much padding was being added. In my case it was 12, so I used a negative margin to get rid of it. Now everything can now be centered properly