Praetorian
Praetorian

Reputation: 109279

Binding a TextBox's Width to its parent container's ActualWidth

I'm loading a Textbox and a Button into a horizontal StackPanel programmatically. The size of the button (which only contains an Image) is fixed, but I can't get the textbox to fill the available width of its parent. This is what the code looks like:

StackPanel parent = new StackPanel() {
  Orientation = Orientation.Horizontal,
  HorizontalAlignment = HorizontalAlignment.Stretch,
  VerticalAlignment = VerticalAlignment.Top,
};

TextBox textbox = new TextBox() {
  HorizontalAlignment = HorizontalAlignment.Stretch,
  VerticalAlignment = VerticalAlignment.Top,
  //MinWidth = 375,
};

Button btn = new Button() {
  Content = new Image() {
    MaxHeight = 40,
    MaxWidth = 40,
    MinHeight = 40,
    MinWidth = 40,
    Margin = new Thickness( 0 ),
    Source = new BitmapImage( 
      new Uri( "btnimage.png", UriKind.Relative ) ),
  },
  HorizontalAlignment = HorizontalAlignment.Right,
  BorderBrush = new SolidColorBrush( Colors.Transparent ),
  Margin = new Thickness( 0 ),
};
btn.Click += ( ( s, e ) => OnBtnClicked( s, e, textbox ) );

parent.Children.Add( textbox );
parent.Children.Add( btn );

If I uncomment the MinWidth setting for the textbox it is displayed as I want it to, but I'd like to not have to specify a width explicitly. I tried adding a binding as follows but that doesn't work at all (the textbox just disappears!)

Binding widthBinding = new Binding() {
  Source = parent.ActualWidth,
};
passwdBox.SetBinding( TextBox.WidthProperty, widthBinding );

Thanks for your help in advance!

Upvotes: 1

Views: 6535

Answers (2)

Josh
Josh

Reputation: 69282

The right answer is don't do it. See my answer at this question and the same idea applies to Silverlight on Windows Phone.

In your example, you should be using a DockPanel.

<toolkit:DockPanel>
    <Button toolkit:DockPanel.Dock="Right" />
    <TextBox /> <!-- fill is implied -->
</toolkit:DockPanel>

Upvotes: 0

Austin Lamb
Austin Lamb

Reputation: 3116

Instead of using StackPanel (which always tries to keep elements as small as it can such that they all fit), use a Grid. Then you could do something like this:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*"/> <!-- Note "*" means to use the rest of the space -->
    <ColumnDefinition Width="40"/>
  </Grid.ColumnDefinitions>
  <TextBox Grid.Column="0"/>
  <Button Grid.Column="1">
    <Button.Content>
      <Image .../>
    </Button.Content>
  </Button>
</Grid>

You can convert this to code instead of XAML if you prefer, XAML's just easier to type here on-the-fly.

Upvotes: 7

Related Questions