windows-phone-7bindingtextboxwidthactualwidth

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!


Solution

  • 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.