views:

1161

answers:

2

I have a WPF page with some data entry TextBoxes on it and they look much bigger than the font needs. What determines the height of the textbox? is there a way to squish them up?

The textbox gets bigger and smaller according to the font size it displays (so I don't want to set the height property directly if I can help it.

Thanks

+10  A: 

My guess is that your TextBox's container is causing it to be too large.

Try the following XAML in Kaxaml:

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;

  <Grid VerticalAlignment="Center" HorizontalAlignment="Center">  
    <TextBox Text="Sample text" FontSize="2" />
  </Grid>

</Page>

This renders as a very small text box in the centre of the page. If you remove the VerticalAlignment="Center" and HorizontalAlignment="Center" from the container, then the text box is very large.

The default horizontal and vertical alignments for the Grid and TextBox are Stretch, which basically means that the element doesn't care and will take what it's given. So the layout engine asks the TextBox how big it should be and doesn't get an answer, and so the layout asks the Grid. The Grid doesn't care either so finally it asks the Page/Window, which has a fixed size, and then this size is propagated down the visual tree (taking any margins and padding into consideration along the way). The net result is that the TextBox fills the whole area.

To prove this point, move the alignment attributes from the Grid to the TextBox itself. You can't see a difference visually, though if you set a background colour for the Grid you would.

<Grid Background="Red">
  <TextBox VerticalAlignment="Center" HorizontalAlignment="Center"
           Text="Sample text" FontSize="2" />
</Grid>

If you want to cram the text box's border right up against the text, you can also set Padding="0" on the text box itself.

See this article for more information on the WPF layout system.

Drew Noakes
Of course it fills the container space, the question is why does it make the container space so big? It seems that when it measures the children for size, if the label has a different VerticalAlignment from the textbox then the sizing is also a bit different.
Hi @jifman, I edited my answer to provide you with more detail. Experiment with this in Kaxaml, using different background colours on the different elements so you can see what the otherwise invisible elements are doing. Hope that helps.
Drew Noakes
+1  A: 

Here's an example of what I mean...

<Page
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
  <Page.Resources>
    <Style x:Key="LabelStyle" TargetType="Label">
      <Setter Property="HorizontalAlignment" Value="Right"/>
      <Setter Property="VerticalAlignment" Value="Center"/>
      <Setter Property="VerticalContentAlignment" Value="Center"/>
    </Style>

    <Style x:Key="TextBoxStyle" TargetType="TextBox">
      <Setter Property="HorizontalAlignment" Value="Left"/>
      <Setter Property="VerticalAlignment" Value="Center"/>
      <Setter Property="VerticalContentAlignment" Value="Center"/>
    </Style>

  </Page.Resources>
  <StackPanel>
    <WrapPanel>
      <Label Style="{StaticResource LabelStyle}" Content="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"/>
      <TextBox Style="{StaticResource TextBoxStyle}" Text="{Binding ActualHeight, RelativeSource={RelativeSource Self}, Mode=OneWay}"/>
    </WrapPanel>
    <WrapPanel>
      <Label Style="{StaticResource LabelStyle}" Content="{Binding ActualHeight, RelativeSource={RelativeSource Self}}"/>
      <TextBox Style="{StaticResource TextBoxStyle}" Text="{Binding ActualHeight, RelativeSource={RelativeSource Self}, Mode=OneWay}"/>
    </WrapPanel>
  </StackPanel>
</Page>

If you look at the size you will see the label is a little bigger than the textbox. Changing the VerticalAlignment on the textbox to Top makes it the same size. As an interim measure I just set a margin on the label to -2.