Reputation: 4684
The look of a WPF CheckBox misaligns the check portion with the label (content) portion. The check stays slightly above the content as shown here:
The XAML looks like this:
<CheckBox Content="Poorly aligned CheckBox" Margin="9"/>
The CheckBox is inside a Grid cell. Is there a simple way to make the content and check portions of a XAML CheckBox align vertically? I've tried various combinations of properties with no luck. I saw a similar question here but the answer is way too complex.
Thanks in advance.
EDIT: The problem was caused by the Window FontSize which I set to 14. To re-create the problem set the CheckBox FontSize to 14 (or more). My program is viewed at a distance by factory workers so I allow the Window FontSize to be increased or decreased by the user.
Upvotes: 54
Views: 53559
Reputation: 343
Here's how it was resolved on my end in MAUI
<StackLayout Orientation="Horizontal" Grid.Row="2" VerticalOptions="Center" Margin="10">
<CheckBox
x:Name="chkPaidCall"
VerticalOptions="Center"
Margin="0,0,5,0"
IsVisible="true"
IsChecked="False"/>
<Label
Text="Use Paid Check"
VerticalTextAlignment="Center"
HorizontalTextAlignment="Start"
VerticalOptions="Center"
Margin="0,0,0,0"/>
</StackLayout>
Upvotes: 0
Reputation: 1
In the ControlTemplate TargetType="{x:Type CheckBox}", you will see Width=13 Height=13; add in the Margin="0,4,0,0" (Left, Top, Right, Bottom) and adjust to get the results you like. I have even enlarged the CheckBox and the Glyph Size and then realigned it with the Margin. Here is the complete Template:
<Style x:Key="{x:Type CheckBox}"
TargetType="{x:Type CheckBox}">
<Setter Property="SnapsToDevicePixels"
Value="true" />
<Setter Property="OverridesDefaultStyle"
Value="true" />
<Setter Property="FocusVisualStyle"
Value="{DynamicResource CheckBoxFocusVisual}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<BulletDecorator Background="Transparent">
<BulletDecorator.Bullet>
<!--Width=13 Height=13 CornerRadius=0-->
<Border x:Name="Border"
Width="15"
Height="15"
Margin="0,4,0,0"
CornerRadius="1"
BorderThickness="1">
<Border.BorderBrush>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource BorderLightColor}"
Offset="0.0" />
<GradientStop Color="{DynamicResource BorderDarkColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.BorderBrush>
<Border.Background>
<LinearGradientBrush StartPoint="0,0"
EndPoint="0,1">
<LinearGradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="{DynamicResource ControlLightColor}" />
<GradientStop Color="{DynamicResource ControlMediumColor}"
Offset="1.0" />
</GradientStopCollection>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Border.Background>
<Grid>
<!--Width=7 Height=7-->
<Path Visibility="Collapsed"
Width="8"
Height="8"
Margin="0,0,0,0"
x:Name="CheckMark"
SnapsToDevicePixels="False"
StrokeThickness="2"
Data="M 0 0 L 7 7 M 0 7 L 7 0">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
<Path Visibility="Collapsed"
Width="8"
Height="8"
Margin="0,0,0,0"
x:Name="InderminateMark"
SnapsToDevicePixels="False"
StrokeThickness="2"
Data="M 0 7 L 7 0">
<Path.Stroke>
<SolidColorBrush Color="{DynamicResource GlyphColor}" />
</Path.Stroke>
</Path>
</Grid>
</Border>
</BulletDecorator.Bullet>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="MouseOver">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlMouseOverColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Panel.Background).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource ControlPressedColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[0].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource PressedBorderDarkColor}" />
</ColorAnimationUsingKeyFrames>
<ColorAnimationUsingKeyFrames Storyboard.TargetName="Border"
Storyboard.TargetProperty="(Border.BorderBrush).
(GradientBrush.GradientStops)[1].(GradientStop.Color)">
<EasingColorKeyFrame KeyTime="0"
Value="{StaticResource PressedBorderLightColor}" />
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled" />
</VisualStateGroup>
<VisualStateGroup x:Name="CheckStates">
<VisualState x:Name="Checked">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="CheckMark">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Unchecked" />
<VisualState x:Name="Indeterminate">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
Storyboard.TargetName="InderminateMark">
<DiscreteObjectKeyFrame KeyTime="0"
Value="{x:Static Visibility.Visible}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<!--4,0,0,0-->
<ContentPresenter Margin="5,0,0,0"
VerticalAlignment="Center"
HorizontalAlignment="Left"
RecognizesAccessKey="True" />
</BulletDecorator>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Upvotes: 0
Reputation: 308
There is a simple solution for this without needing to make a text block for the content, and without writing extra code that you don't need. Just use "VerticalContentAlignment". Example:
<CheckBox Content="Sample of Text" VerticalContentAlignment="Center"/>
Upvotes: 21
Reputation: 3471
I know it's too late, but here is a better solution, without setting margins. Margins should be set differently for different heights of TextBlock
or Checkbox
.
<CheckBox VerticalAlignment="Center" VerticalContentAlignment="Center">
<TextBlock Text="Well aligned Checkbox" VerticalAlignment="Center" />
</CheckBox>
Update:
It's worth checking out @nmarler's comment below.
Upvotes: 90
Reputation: 812
Applying negative Top padding works just fine for my layout:
<CheckBox Content="Poorly aligned CheckBox" Padding="4,-3,0,0" Margin="9"/>
Upvotes: 1
Reputation: 1637
Place an empty CheckBox and the content as separate controls in a StackPanel with horizontal orientation. This works with any font size.
<StackPanel Orientation="Horizontal">
<CheckBox VerticalAlignment="Center" />
<TextBlock VerticalAlignment="Center" Text="Option X" />
</StackPanel />
Upvotes: 3
Reputation: 17176
My checkboxes are aligned fine, so I wonder what's different about yours. The only apparent difference is that you are using a larger font than me, which reminds me of the following question:
WPF CheckBox style with the TextWrapping
Your problem may be that if the content is a textblock, the checkbox is top-justified, which may look odd when the font size is increased. So my guess is, try using an AccessText as the Content of the CheckBox instead:
<CheckBox Margin="9"><AccessText>Better aligned CheckBox?</AccessText></CheckBox>
Upvotes: 0
Reputation: 84647
The default Style of a CheckBox
don't look like that in WPF. It aligns perfectly in both XP and Windows 7. Can you give a better description of how to reproduce this problem?
Two things I can think of to get the offset that you're seeing is either changing the Padding
or the VerticalContentAlignment
. The default CheckBox
value for VerticalContentAlignment
is Top
and a CheckBox
with Content
has Padding
set to "4,0,0,0"
. Try to change these two around and see if it makes any difference.
Here is a comparison
From the following Xaml
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<CheckBox Grid.Row="0"
Content="Poorly aligned CheckBox" Margin="9" />
<CheckBox Grid.Row="1"
Content="Padding=4,4,0,0" Margin="9" Padding="4,4,0,0"/>
<CheckBox Grid.Row="2"
Content="Vertical Center" Margin="9"
VerticalContentAlignment="Center"/>
<CheckBox Grid.Row="3"
Content="Vertical Top" Margin="9"
VerticalContentAlignment="Top"/>
</Grid>
Upvotes: 17
Reputation: 7103
Edit - New Answer: (previous was no good)
Not the best way i believe , but can do the work:
<CheckBox>
<TextBlock Text="Poorly aligned CheckBox" Margin="0,-2,0,0"/>
</CheckBox>
Using negative margin to push the content up, result:
Upvotes: 31