0

In WinUI 3, TextBox and NumberBox controls support a Header property that adds text above the control to label the input field. I would like the same sort of thing for a DropDownButton control, but the Header property is not supported for that control.

I tried working around this limitation by wrapping the DropDownButton with a StackPanel to group it with a TextBlock, but the text doesn't line up correctly with the text of the headers of other controls in the same row.

Is there a way to do this without abandoning the use of the Header property altogether? I know that I could just not use the Header property for any of the controls and instead have 2 rows for each row of input controls, one for text labels and another for the input controls. It seems like a kludge to do it that way.

Below is an example for illustration. In the following user control, the TextBlock text for the B0 (T) and Pulse Sequence labels don't align with the headers for the other controls in the same row.

<?xml version="1.0" encoding="utf-8"?>
<UserControl
    x:Class="The.Fully.Qualified.Class.Name"
    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">

    <Grid x:Name="MrAcquisitionParametersGrid" 
          Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"
          Style="{ThemeResource BorderedGridStyle}">
        <Grid.Resources>

        </Grid.Resources>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>

        <TextBlock Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="4" 
                       Margin="10 10 10 0" 
                       HorizontalAlignment="Left">
                MR Acquisition Parameters
        </TextBlock>

        <StackPanel Grid.Row="1" Grid.Column="0">
            <TextBlock Style="{StaticResource LabelTextStyle}">
                B0 (T)
            </TextBlock>
            <DropDownButton Content="1.5" x:Name="FieldStrength">
                <DropDownButton.Flyout>
                    <MenuFlyout>
                        <MenuFlyoutItem Text="1.5"/>
                        <MenuFlyoutItem Text="3.0"/>
                        <MenuFlyoutItem Text="4.7"/>
                        <MenuFlyoutItem Text="7.0"/>
                        <MenuFlyoutItem Text="9.4"/>
                    </MenuFlyout>
                </DropDownButton.Flyout>
            </DropDownButton>
        </StackPanel>
        <NumberBox Grid.Row="1" Grid.Column="1" 
                   Width="90"
                   Header="Flip Angle (°)"
                   x:Name="FlipAngle"/>

        <StackPanel Grid.Row="2" Grid.Column="0">
            <TextBlock Style="{StaticResource LabelTextStyle}">
                Pulse Sequence
            </TextBlock>
            <DropDownButton Content="FLASH" x:Name="PulseSequence">
                <DropDownButton.Flyout>
                    <MenuFlyout>
                        <MenuFlyoutItem Text="FLASH"/>
                        <MenuFlyoutItem Text="RARE"/>
                    </MenuFlyout>
                </DropDownButton.Flyout>
            </DropDownButton>
        </StackPanel>
        <NumberBox Grid.Row="2" Grid.Column="1" 
                   Header="Acquisition Interval (s)"
                   x:Name="AcquisitionInterval"/>
        <NumberBox Grid.Row="2" Grid.Column="2" 
                   Header="Echo Time (ms)"
                   x:Name="EchoTime"/>
        <NumberBox Grid.Row="2" Grid.Column="3" 
                   Header="Repetition Time (ms)"
                   x:Name="RepetitionTime"/>
    </Grid>
</UserControl>

enter image description here

Matt
  • 2,339
  • 1
  • 21
  • 37

1 Answers1

1

You can see the style of NumberBoxes in Generic.xaml.

<Style TargetType="controls:NumberBox">
    ...
</Style>

You can find that TextBoxTopHeaderMargin is applied to the header control. TextBoxTopHeaderMargin is also defined in the Generic.xaml.

<Thickness x:Key="TextBoxTopHeaderMargin">0,0,0,8</Thickness>

So something like this should do:

<Grid
    Margin="10"
    ColumnDefinitions="Auto,Auto"
    RowDefinitions="Auto,Auto">
    <NumberBox
        Grid.Row="0"
        Grid.Column="0"
        Header="Header" />

    <Grid
        Grid.Row="1"
        Grid.Column="0"
        RowDefinitions="Auto,Auto">
        <TextBlock
            Grid.Row="0"
            Margin="{StaticResource TextBoxTopHeaderMargin}"
            Text="Select an item" />
        <DropDownButton
            Grid.Row="1"
            Content="Items">
            <DropDownButton.Flyout>
                <MenuFlyout>
                    <MenuFlyoutItem Text="Item 1" />
                    <MenuFlyoutItem Text="Item 2" />
                    <MenuFlyoutItem Text="Item 3" />
                </MenuFlyout>
            </DropDownButton.Flyout>
        </DropDownButton>
    </Grid>

    <NumberBox
        Grid.Row="1"
        Grid.Column="1"
        Header="Header" />
</Grid>
Andrew KeepCoding
  • 7,040
  • 2
  • 14
  • 21
  • That doesn't seem to work. When I tried it, the baseline of the text above the DropDownButton didn't line up with the baseline of the header text above other controls that are in the same row. – Matt Jul 19 '23 at 22:18
  • Weird. The code is from a sample app I created for this answer. I update my answer with the code I used to check the alignments. – Andrew KeepCoding Jul 19 '23 at 22:52
  • I played around with it some more yesterday and found that it does work if I remove all non-default margins from all of the other controls. I suppose with enough tinkering I could make something workable. Ultimately, what I've decided is that WinUI is just too bleeding edge a technology at this point in time and lacking the supporting tools (like a WYSIWYG tool for UI design) necessary to make it productive for me to use routinely. – Matt Jul 21 '23 at 14:24
  • Yes. If you want to align your controls, you need to remove custom margins or at least apply margins that result aligning them. – Andrew KeepCoding Jul 21 '23 at 15:13