1

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!

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Praetorian
  • 106,671
  • 19
  • 240
  • 328

2 Answers2

7

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.

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Austin Lamb
  • 3,116
  • 1
  • 22
  • 13
0

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>
Community
  • 1
  • 1
Josh
  • 68,005
  • 14
  • 144
  • 156
  • That looks like what I need but I can't find `DockPanel` in the Silverlight Toolkit for Windows Phone. I just tried re-installing it to make sure I have the latest release but still no luck. – Praetorian Dec 31 '10 at 19:57
  • Care should be taken when deciding to use toolkit components. These will add to the overall size of the Xap which can be an important consideration on WP7. If the only reason to add a toolkit dll is to get this one feature working an alternative non-toolkit solution should be sought. – AnthonyWJones Dec 31 '10 at 20:47
  • Very good point, Anthony. If you are not already using the Silverlight toolkit then I would use a Grid. But having DockPanel is extremely useful for a variety of layouts. You can almost always use a Grid for such layouts but as you can see in Austin's answer, Grid-based layouts can get become pretty verbose. – Josh Jan 01 '11 at 00:51