Vertically align the contents of a WPF flag with a flag

I have a checkbox whose XAML markup looks like this:

<CheckBox HorizontalContentAlignment="Stretch"> <StackPanel Orientation="Vertical"> <TextBox x:Name="editTextBox" Text="{Binding Path=Caption, Mode=TwoWay}" TextWrapping="Wrap" Visibility="{Binding Path=IsBeingEdited, Converter={StaticResource booleanToVisibilityConverter}}" /> <TextBlock x:Name="itemText" TextWrapping="Wrap" Text="{Binding Path=Caption}" Visibility="{Binding Path=IsBeingEdited, Converter={StaticResource reverseBooleanToVisibilityConverter}}"> </TextBlock> </StackPanel> </CheckBox> 

The idea is that I can switch between TextBlock (display) and TextBox (edit). However, when the application starts, the visual check of the CheckBox (the checked square) is vertically centered. I would like it to be aligned with the top of the TextBlock / TextBox.

I noticed that when I turn on only TextBlock (so there is no StackPanel, without a TextBox), the checkbox actually aligns with the top of the TextBlock, so I assume that I am missing some settings on the StackPanel

+7
checkbox wpf wpf-controls
source share
2 answers

First of all, do not waste time on VerticalAlignment or VerticalContentAlignment (or even ControlTemplate ). They are not going to do what you want or can expect.

As described in MSDN, a BulletDecorator (which is the control that CheckBox and RadioButton uses to render the radio / check buttons) will automatically set the icon position. You have no additional control over this:

A Bullet always aligns with the first line of text when a Child object is a text object. If the Child object is not a text object, the Bullet is centered on the Child object.

If you do not change the control template (optional), you can place the radio / check icon at the top if the content is text.

So, if you do something like this, it won’t look good, because you won’t be able to move the icon no matter how many VerticalAlignment properties you are trying to set.

 <RadioButton> <StackPanel> <TextBlock Text="First line"/> <TextBlock Text="Something else"/> </StackPanel> </RadioButton> 

BUT , fortunately, you can put anything you want into a TextBlock using InlineUIContainer . The text (or content) in the first line will automatically determine the position of the icon. If you want something under the first line that is not text, just use <Linebreak/> and then <InlineUIContainer/>

Here is an example that an oversized TextBox to show more clearly what is happening.

 <RadioButton> <TextBlock VerticalAlignment="Top" TextWrapping="Wrap"> <TextBlock Text="Products with &lt;" VerticalAlignment="Center" Margin="0,0,5,0"/> <InlineUIContainer BaselineAlignment="Center"> <TextBox FontSize="30" Width="25" Text="10" Margin="0,0,5,0"/> </InlineUIContainer> <TextBlock VerticalAlignment="Center" Margin="0,0,5,0"> <Run Text="days" FontWeight="Bold"/> <Run Text="inventory" /> </TextBlock> <LineBreak/> <InlineUIContainer> <StackPanel> <CheckBox Content="Include unsold products" /> <CheckBox Content="Include something else" /> </StackPanel> </InlineUIContainer> </TextBlock> </RadioButton> 
+5
source share

CheckBox.Content does not give you much control over how things are displayed. Try instead:

  <DockPanel VerticalAlignment="Top"> <!-- can also be center or bottom --> <CheckBox/> <Grid> <TextBox x:Name="editTextBox" Text="{Binding Path=Caption, Mode=TwoWay}" TextWrapping="Wrap" Visibility="{Binding Path=IsBeingEdited, Converter={StaticResource booleanToVisibilityConverter}}" /> <TextBlock x:Name="itemText" TextWrapping="Wrap" Text="{Binding Path=Caption}" Visibility="{Binding Path=IsBeingEdited, Converter={StaticResource reverseBooleanToVisibilityConverter}}"> </Grid> </DockPanel> 
-3
source share

All Articles