How to vertically align XAML UWP checkbox - xaml

I am trying to vertically align a checkbox. The actual box appears at the top. I want it to appear in the middle.
This is the XAML:
<CheckBox FontSize="100" Content="Test" VerticalContentAlignment="Center" VerticalAlignment="Center" HorizontalAlignment="Center" HorizontalContentAlignment="Center"/>
This is what it looks like:
I have seen similar questions on SO, but the answer was to use VerticalContentAlignment. This does not work. Some answers have suggested using negative padding or margins, which does not scale. So please don't mark as duplicate, this has not really been answered. Or perhaps it was answered for WPF but not for UWP.
I am aware that you can change the style of the control, but that is a lot of work for something that should just work out of the box.
I am using VS 2019 16.6.2 with UWP v6.2.10
Update
This is what I would like my CheckBox to look.

How to vertically align XAML UWP checkbox
For the requirement, the better way is modify the checkbox's default layout. The default layout is Column, we need to change it to Row. And I will share the a part of style and you could use it directly.
<Grid
x:Name="RootGrid"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="{TemplateBinding CornerRadius}"
>
<Grid.RowDefinitions>
<RowDefinition Height="32" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Grid
Height="32"
HorizontalAlignment="Center"
VerticalAlignment="Top"
>
<Rectangle
x:Name="NormalRectangle"
Width="20"
Height="20"
Fill="{ThemeResource CheckBoxCheckBackgroundFillUnchecked}"
Stroke="{ThemeResource CheckBoxCheckBackgroundStrokeUnchecked}"
StrokeThickness="{ThemeResource CheckBoxBorderThemeThickness}"
UseLayoutRounding="False"
/>
<FontIcon
x:Name="CheckGlyph"
FontFamily="{ThemeResource SymbolThemeFontFamily}"
FontSize="20"
Foreground="{ThemeResource CheckBoxCheckGlyphForegroundUnchecked}"
Glyph=""
Opacity="0"
/>
</Grid>
<ContentPresenter
x:Name="ContentPresenter"
Grid.Row="1"
Margin="{TemplateBinding Padding}"
HorizontalAlignment="Center"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
AutomationProperties.AccessibilityView="Raw"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}"
TextWrapping="Wrap"
/>
For the complete style please refer this link.
Update
If do not want to edit the default style, we could make custom checkbox, and edit the layout in OnApplyTemplate method.
public class CustomCheckBox : CheckBox
{
protected override void OnApplyTemplate()
{
base.OnApplyTemplate();
var normalRectangle = GetTemplateChild("NormalRectangle") as Rectangle;
var rootGrid = normalRectangle.Parent as Grid;
Grid.SetColumnSpan(rootGrid, 2);
rootGrid.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center;
var contentPresenter = GetTemplateChild("ContentPresenter") as ContentPresenter;
Grid.SetColumn(contentPresenter, 0);
Grid.SetColumnSpan(contentPresenter, 2);
contentPresenter.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Center;
}
}
Usage
<local:CustomCheckBox FontSize="100" Content="Test" VerticalAlignment="Center" HorizontalAlignment="Center" />
Update 1
use the following to replace OnApplyTemplate content.
var normalRectangle = GetTemplateChild("NormalRectangle") as Rectangle;
var rootGrid = normalRectangle.Parent as Grid;
Grid.SetColumnSpan(rootGrid, 2);
rootGrid.HorizontalAlignment = Windows.UI.Xaml.HorizontalAlignment.Left
rootGrid.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;

Related

Customize GroupItem HeaderTemplate UWP

I'm doing an UWP project and I wan't to customize the HeaderTemplate of the group items, but I m unable to find how to fully customize it.
<ListView ItemsSource="{x:Bind ContactsCVS.View}"
ItemTemplate="{StaticResource ContactListViewTemplate}"
SelectionMode="Single"
ShowsScrollingPlaceholders="True"
Grid.Row="1"
Grid.ColumnSpan="2">
<ListView.GroupStyle>
<GroupStyle >
<GroupStyle.HeaderTemplate>
<DataTemplate x:DataType="data:GroupInfoList">
<TextBlock Text="{x:Bind Key}"
Style="{ThemeResource itleTextBlockStyle}"/>
<!-- Can't fully customize this part ?-->
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ListView.GroupStyle>
</ListView>
I m basing my test on this official example :
https://github.com/Microsoft/Windows-universal-samples/blob/de1bb527ec0327b767397d4c1a74a797356f4357/Samples/XamlListView/cs/Samples/SimpleListViewSample/SimpleListViewSample.xaml
I try to replace the letters A, B, C... With a blue strip and custom text. Looks very simple but can't figure out how it works.
Thanks
The HeaderTemplate defines the template of the header content, but the actual control that displays this content is a ListViewHeaderItem. You can actually simply do this if you want:
<GroupStyle.HeaderTemplate>
<DataTemplate x:DataType="data:GroupInfoList">
<Border Background="LightSkyBlue">
<TextBlock Text="My custom text" />
</Border>
</DataTemplate>
</GroupStyle.HeaderTemplate>
When the ListView is rendered, the ListViewHeaderItem for each group will show the above content, but the control itself still has its own default style.
If you want to style the control as well, to maybe make it stretch horizontally or something, you'll have to create your own style for HeaderContainerStyle:
<GroupStyle.HeaderContainerStyle>
<Style TargetType="ListViewHeaderItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListViewHeaderItem">
<ContentPresenter
x:Name="ContentPresenter"
Background="Red"
Margin="0"
HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalContentAlignment="Stretch"
Content="{TemplateBinding Content}"
ContentTemplate="{TemplateBinding ContentTemplate}"
ContentTransitions="{TemplateBinding ContentTransitions}" />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</GroupStyle.HeaderContainerStyle>
The ContentPresenter is responsible for showing the Content of the control, in this case the content is whats inside the HeaderTemplate.

Update color of SelectionIndicator in NavigationView

I'm using the NavigationView control to provide the left pane hamburger menu navigation in my UWP app.
I'd like to change the color of the selection indicator (the little rectangle that shows up next to the item you selected).
In generic.xaml I can see the color is being set to the system accent color:
<Style TargetType="NavigationViewItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="NavigationViewItem">
<Grid
x:Name="LayoutRoot"
Height="40"
Background="{TemplateBinding Background}"
Control.IsTemplateFocusTarget="True">
<!-- Wrap SelectionIndicator in a grid so that its offset is 0,0 - this enables the offset animation. -->
<Grid
HorizontalAlignment="Left"
VerticalAlignment="Center">
<Rectangle
x:Name="SelectionIndicator"
Width="6"
Height="24"
Fill="{ThemeResource NavigationViewSelectionIndicatorForeground}"
Opacity="0.0"/>
</Grid>
<Border
x:Name="RevealBorder"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}" />
<Grid Height="40" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="IconColumn" Width="48" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Viewbox x:Name="IconBox"
Child="{TemplateBinding Icon}"
Margin="16,12"/>
<ContentPresenter x:Name="ContentPresenter"
Grid.Column="1"
ContentTransitions="{TemplateBinding ContentTransitions}"
ContentTemplate="{TemplateBinding ContentTemplate}"
Content="{TemplateBinding Content}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
Margin="{TemplateBinding Padding}"/>
</Grid>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Is there a way in my pages XAML file (that uses the NavigationView) to change the color of the rectangle Fill from NavigationViewSelectionIndicatorForeground to some value I set?
I know I could copy over the entire template and update the copy, and set the template on the NavigationView, but it seems like a lot of overhead just to change one value.
You can just define your own brush with x:Key="NavigationViewSelectionIndicatorForeground" for example in App.xaml:
<Application ...>
<Application.Resources>
<SolidColorBrush x:Key="NavigationViewSelectionIndicatorForeground"
Color="Yellow" />
</Application.Resources>
</Application>
Alternatively you could also declare the resource in the scope of your Page or even in your NavigationView's Resources, it just needs to be in the path in the XAML tree leading to the NavigationView.
Because your resource goes later in the cascade, it will override the default NavigationViewSelectionIndicatorForeground with your defined brush.

How to vertically centre text in a Xamarin Forms Entry on UWP?

I have a Xamarin Forms project (v2.5) where I have a text Entry control in my Xaml file. I need the entry to be taller than default, so I specify a HeightRequest of 60, which works fine, apart from the text itself is aligned to the top of the Entry control.
<Entry Text="{Binding CustomerNameText}" HeightRequest="60" VerticalOptions="FillAndExpand" HorizontalOptions="FillAndExpand" IsEnabled="{Binding CustomerNameEntryEnabled}" Focused="Entry_Focused" Unfocused="Entry_Unfocused" />
Which looks like:
I added a custom renderer:
public class CustomEntryRenderer : EntryRenderer
{
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if(this.Control != null)
{
this.Control.VerticalAlignment = Windows.UI.Xaml.VerticalAlignment.Center;
this.Control.Height = 60;
}
}
}
But this doesn't work. The HeightRequest in the Xaml doesn't seem to work anymore, so I added the height in the custom renderer. But the text alignment stays at the top.
Can anyone tell me how to get the text vertically centered?
The correspondent native control of Entry is TextBox in UWP app, see Renderer Base Classes and Native Controls for more details. The VerticalAlignment property means that setting current control to vertical center in the parent control, not for the text inside. Only properties like TextAlignment will take effects on the text. Since Textbox in UWP app doesn't have the property VerticalTextAlignment, you cannot set the text to vertical center directly. But you could change the style template of TextBox as a workaround.
Create a new style for the Textbox, and to set the VerticalAlignment property to center to both ContentPresenter and ScrollViewer controls inside the ControlTemplate. And then apply the style in the custom render.
The style in App.xaml
<Style x:Key="TextBoxStyle1" TargetType="TextBox">
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="TextBox">
<Grid>
...
<Border x:Name="BorderElement" Background="{TemplateBinding Background}" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}" Grid.ColumnSpan="2" Grid.RowSpan="1" Grid.Row="1"/>
<ContentPresenter x:Name="HeaderContentPresenter" VerticalAlignment="Center" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.ColumnSpan="2" FontWeight="Normal" Foreground="{ThemeResource TextControlHeaderForeground}" Margin="0,0,0,8" Grid.Row="0" TextWrapping="{TemplateBinding TextWrapping}" Visibility="Collapsed" x:DeferLoadStrategy="Lazy"/>
<ScrollViewer x:Name="ContentElement" VerticalAlignment="Center" AutomationProperties.AccessibilityView="Raw" HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}" HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}" IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}" IsTabStop="False" IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}" VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}" ZoomMode="Disabled"/>
<TextBlock x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Foreground="{Binding PlaceholderForeground, RelativeSource={RelativeSource Mode=TemplatedParent}, TargetNullValue={ThemeResource TextControlPlaceholderForeground}}" IsHitTestVisible="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1" Text="{TemplateBinding PlaceholderText}" TextWrapping="{TemplateBinding TextWrapping}" TextAlignment="{TemplateBinding TextAlignment}"/>
<Button x:Name="DeleteButton" AutomationProperties.AccessibilityView="Raw" BorderThickness="{TemplateBinding BorderThickness}" Grid.Column="1" FontSize="{TemplateBinding FontSize}" IsTabStop="False" MinWidth="34" Margin="{ThemeResource HelperButtonThemePadding}" Grid.Row="1" Style="{StaticResource DeleteButtonStyle}" VerticalAlignment="Stretch" Visibility="Collapsed"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Custom render:
protected override void OnElementChanged(ElementChangedEventArgs<Entry> e)
{
base.OnElementChanged(e);
if (this.Control != null)
{
this.Control.Height = 60;
Control.Style = (Windows.UI.Xaml.Style)App.Current.Resources["TextBoxStyle1"];
}
}
I don't think that is needed a custom renderer, just center and expand.
VerticalOptions = "LayoutOptions.CenterAndExpand"
I know it's late, but below code works for Android to center text in Entry,it shuold work for UWP too:
this.Control.Gravity = GravityFlags.CenterHorizontal;
this.Control.Gravity = GravityFlags.Center;
Let me know,if it helps
//Try this:
VerticalOptions = "CenterAndExpand"
If this doesn't work go for custom renderer

Callisto Custom Dialog Custom Styling for Windows App

Is there a way to customize the styling of the Callisto Custom Dialog other than the background? I want to change the font size and color of the title property of the Custom Dialog. Any suggestions without messing with the base style?
Reference: https://github.com/timheuer/callisto/wiki/CustomDialog
The CustomDialog's template calculates it's title's Foreground to a colour which contrasts with the Background and sets the FontSize to 26.6667:
<StackPanel Margin="13,19,13,25" HorizontalAlignment="Center" Width="{TemplateBinding Width}" MaxWidth="680">
<local:DynamicTextBlock Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Background, Converter={StaticResource ColorContrast}}" x:Name="PART_Title" Text="{TemplateBinding Title}" FontFamily="Segoe UI" FontSize="26.6667" FontWeight="Light" Margin="0,0,0,8" />
<ContentPresenter Margin="0" x:Name="PART_Content" Foreground="{Binding RelativeSource={RelativeSource Mode=TemplatedParent}, Path=Background, Converter={StaticResource ColorContrast}}" />
</StackPanel>
If you want to change these you'll need to retemplate the dialog. You can copy the template from Callisto's generic.xaml and then replace the Foreground and FontSize properties. You may want to use a TemplateBinding so you can set them on the CustomDialog when you call it:
<StackPanel Margin="9,5" HorizontalAlignment="Center" Width="{TemplateBinding Width}" MaxWidth="680">
<callisto:DynamicTextBlock Foreground="{TemplateBinding Foreground}" x:Name="PART_Title" Text="{TemplateBinding Title}" FontFamily="Segoe UI" FontSize="{TemplateBinding FontSize}" FontWeight="Light" Margin="0,0,0,8" />
<ContentPresenter Margin="0" x:Name="PART_Content" Foreground="{TemplateBinding Foreground}" />
</StackPanel>
Then set them to your own resources:
<callisto:CustomDialog Background="{ThemeResource MyCustomDialogBackground}" Foreground="{ThemeResource MyCustomDialogForeground}" Title="Lorem ipsum" Template="{StaticResource CustomDialogControlTemplate1}"></callisto:CustomDialog>

Windows Phone 8 - Center PanoramaItem.Header

I'm developing a Panorama App for Windows Phone 8 and I got a small problem. I added an image to the header of one of my Panorama.Item (and it shows up fine) but I'd love it to be centered and not aligned left. I don't even know if it's possible or if you can't change the alignment at all. Here's the code for the header I'm talking about:
<phone:PanoramaItem.Header>
<Image x:Name="Logo" Height="100" HorizontalAlignment="Center" Tap="Logo_Tap" />
</phone:PanoramaItem.Header>
The HorizontalAlignment="Center"-Property unfortunately doesn't seem to do it. Any help would be appreciated.
I would avoid using a hard coded width. The proper way to do this would be to override the Template on the PanoramaItem, like this (They key part being changing the HorizontalAlignment on the header ContentControl)
<ControlTemplate x:Key="CenteredHeaderPanoramaItemTemplate" TargetType="phone:PanoramaItem">
<Grid Background="{TemplateBinding Background}" Margin="12,0,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<ContentControl x:Name="header" CharacterSpacing="-35" ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" FontSize="66" FontFamily="{StaticResource PhoneFontFamilySemiLight}" Margin="12,-2,0,38" HorizontalAlignment="Stretch">
<ContentControl.RenderTransform>
<TranslateTransform x:Name="headerTransform"/>
</ContentControl.RenderTransform>
</ContentControl>
<ContentPresenter Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" Grid.Row="1" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
</Grid>
</ControlTemplate>
Then just assign the Template using a StaticResource
<phone:PanoramaItem Template="{StaticResource CenteredHeaderPanoramaItemTemplate}">
<phone:PanoramaItem.Header>
<Image x:Name="Logo" Height="100" HorizontalAlignment="Center" Tap="Logo_Tap" />
</phone:PanoramaItem.Header>
<Grid x:Name="PanoramaItemContent">
</Grid>
</phone:PanoramaItem>
The simplest way is:
<phone:PanoramaItem.Header>
<Grid Width="432">
<Image x:Name="Logo"
Height="100"
HorizontalAlignment="Center"
Tap="Logo_Tap" />
</Grid>
</phone:PanoramaItem.Header>
<phone:PanoramaItem.Header>
<Grid HorizontalAlignment="Center">
<Image x:Name="Logo" Height="100" Tap="Logo_Tap" />
</Grid>
</phone:PanoramaItem.Header>
try this