23

I am trying to modify my simple control so that the text box does not grow as the user types in long text. I took a look at some solutions posted here at Stackoverflow that suggest using a Grid and an invisible Border and binding the Width of the text box to the ActualWidth of the Border, but I can't seem to get it to work in my setup.

Here is the xaml of my control:

<StackPanel Margin="5,0">
<WrapPanel Margin="0,0,0,5">
  <TextBlock Foreground="White" Margin="0,0,2,0">TEXT</TextBlock>
  <TextBlock Foreground="#FF0099CC" FontWeight="Bold">MORE TEXT</TextBlock>
</WrapPanel>
<Border Margin="2,4,0,4" BorderThickness="1" SnapsToDevicePixels="True" Background="Black"
        BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}">
  <StackPanel Orientation="Horizontal">
    <Image Source="..\Resources\zoom.png" Width="13"/>
    <TextBox Foreground="White" Background="Black" BorderBrush="Transparent">THIS IS SOME TEXT</TextBox>
  </StackPanel>
</Border>
</StackPanel>

Any ideas? I need the zoom.png to appear "inside" of the text box so I use a horizontal stack panel and just place the image and text box side by side, both surrounded by the same border.

Is there a way for me to stop my text box from auto growing as text is typed?

Thanks.

UPDATE:

Below is the xaml I am testing with.

<Window x:Class="Desktop.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:composite="http://www.codeplex.com/CompositeWPF"
    Title="MyShell" Height="50" Width="900"
    WindowStyle="None"
    ShowInTaskbar="False"        
    AllowsTransparency="True"
    Background="Transparent"
    ResizeMode="CanResizeWithGrip"
    WindowStartupLocation="CenterScreen">
  <Border BorderBrush="Black"
                BorderThickness="1.5"
                CornerRadius="5"
                Background="Gray">
    <ItemsControl composite:RegionManager.RegionName="MainRegion">
      <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
          <WrapPanel></WrapPanel>
        </ItemsPanelTemplate>
      </ItemsControl.ItemsPanel>
    </ItemsControl>
  </Border>
</Window>


<UserControl x:Class="Desktop.SearchTextBox"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Height="50" Margin="0">
  <StackPanel Margin="5,0">
    <WrapPanel Margin="0,0,0,5">
      <TextBlock Foreground="White" Margin="0,0,2,0">TEXT</TextBlock>
      <TextBlock Foreground="#FF0099CC" FontWeight="Bold">MORE TEXT</TextBlock>
    </WrapPanel>
    <Border Margin="2,4,0,4" BorderThickness="1" SnapsToDevicePixels="True" Background="Black"
        BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}">
        <Grid x:Name="grdTest">
          <Image HorizontalAlignment="Left" Source="..\Resources\zoom.png" Width="13"/>
          <TextBox Margin="16,0,0,0"  Foreground="White" Background="Black" BorderBrush="Transparent" Width="{Binding ElementName=grdTest, Path=ActualWidth}">THIS IS SOME TEXT</TextBox>
        </Grid>
    </Border>
  </StackPanel>
</UserControl>

I just add my user control to the Window's MainRegion.

Flack
  • 5,727
  • 14
  • 69
  • 104

7 Answers7

17

I did some more searching and found the solution. I used the below Grid to replace the grid in my original post and now the text box keeps its original size and does not auto grow on long user input. Thanks to all who looked into this.

      <Grid>
        <Grid.ColumnDefinitions>
          <ColumnDefinition Width="Auto"/>
          <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
          <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Image Source="..\Resources\zoom.png" Width="13"/>
        <Border x:Name="b" Grid.Column="1"/>
        <TextBox Width="{Binding ActualWidth, ElementName=b}" Foreground="White" Background="Black" BorderBrush="Transparent"
          Grid.Column="1"
          VerticalAlignment="Center"
          Text="THIS IS SOME TEXT"/>
      </Grid>
Flack
  • 5,727
  • 14
  • 69
  • 104
  • Thanks. I tried this and it worked with one flaw for me. It cannot be used if your using a scrollviewer. I originally had one and what was happening is the textbox grew when the UI grew but would not shrink when the UI shrunk. – famousKaneis Jun 01 '15 at 17:08
  • 1
    @nameless You have to set `HorizontalScrollBarVisibility = "False"` for your Scrollviewer to get your Textbox to follow the windows width as it shrinks. – M463 Jul 30 '15 at 14:03
  • This should have been fixed in WPF itself if this is the only real solution ... (I didn't find anything better myself yet and we're in 2016 ... ) – Arwin Mar 16 '16 at 19:13
  • Actually, I am coming back on this. The Border trick is not necessary if you set the HorizontalScrollBarVisibility to disabled for the Grid or ListView's own ScrollViewer. After I did that, everything behaved as I expected and hoped. – Arwin Mar 17 '16 at 22:37
10

Name the Grid as x:Name="grdTest" and try this

<Grid x:Name="grdTest"> 
    <Image HorizontalAlignment="Left" Source="..\Resources\zoom.png" Width="13"/> 
    <TextBox Margin="16,0,0,0"  Foreground="White" Background="Black" BorderBrush="Transparent"     
             Width="{Binding ElementName=grdTest, Path=ActualWidth}">THIS IS SOME TEXT</TextBox> 
</Grid> 
Joe
  • 6,773
  • 2
  • 47
  • 81
Kishore Kumar
  • 21,449
  • 13
  • 81
  • 113
  • Hey Kishore. I bound the text box width to the grid's width and the text box does not grow as I type but now when I put the user control in a window (such as adding it to a wrap panel in a window) it always takes up the entire width of the window. Is there a way to have it limited to the width of the wrap panel that contains the two text blocks? – Flack Sep 16 '10 at 18:56
  • I have updated my original post to include the xaml I am testing with. – Flack Sep 17 '10 at 12:57
10

Try to put ScrollViewer.HorizontalScrollBarVisibility="Disabled" inside Grid.

Cosmin
  • 21,216
  • 5
  • 45
  • 60
kostas
  • 101
  • 1
  • 2
1

To stop the grow behavior set an explicit size to the TextBox or place it in a grid with the HorizontalAlignment set to stretch

Option 1:

<TextBox Width="60">THIS IS SOME TEXT</TextBox>

Option 2:

<TextBox HorizontalAlignment="Stretch">THIS IS SOME TEXT</TextBox>
anhoppe
  • 4,287
  • 3
  • 46
  • 58
rudigrobler
  • 17,045
  • 12
  • 60
  • 74
  • 1
    Can you post what the xaml would look like? I tried wrapping the text box in a grid and setting the text box's HorizontalAlignment to Stretch but that didn't prevent the text box from growing as text was typed. (I also tried setting the Grid's HorizontalAlignment to Stretch in case I misunderstood but the result was the same.) – Flack Sep 15 '10 at 20:40
1

I had a very similar issue, and it turned out that my Window property "SizeToContent" was set to "WidthAndHeight", I removed setting that property, (which then defaults to "Manual") and this fixed my similar issue.

  • I also manually set the Height and Width of the Window to my desired starting size. (but it is still a resizable window) – user3657054 Aug 04 '22 at 23:11
0

This article shows a solution for a textbox that is displayed inside a scrollviewer's viewport (in treeview or listbox). A PART_MeasureTextBlock is used (bound to the textbox) to determine the available size and set it to the textbox. Please have look here and tell me what you think about it: http://www.codeproject.com/Articles/802385/A-WPF-MVVM-In-Place-Edit-TextBox-Control

user3313608
  • 241
  • 3
  • 4
0

To scale the border containing the textbox to the width of the outter stack panel, change the inner stack panel to a grid and set a left margin on the text box so it doesn't overlap with the image. Also set the image's horizontal alignment to left (if that is where you want it) or it will default to the center of the border.

        <StackPanel Margin="5,0">
        <WrapPanel Margin="0,0,0,5">
            <TextBlock Foreground="White" Margin="0,0,2,0">TEXT</TextBlock>
            <TextBlock Foreground="#FF0099CC" FontWeight="Bold">MORE TEXT</TextBlock>
        </WrapPanel>
        <Border Margin="2,4,0,4" BorderThickness="1" SnapsToDevicePixels="True" Background="Black"
                BorderBrush="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}">
            <Grid>
                <Image HorizontalAlignment="Left" Source="..\Resources\zoom.png" Width="13"/>
                <TextBox Margin="16,0,0,0"  Foreground="White" Background="Black" BorderBrush="Transparent">THIS IS SOME TEXT</TextBox>
            </Grid>
        </Border>
    </StackPanel>
PhilB
  • 11,732
  • 2
  • 19
  • 15
  • Thanks. I was looking for a way to do it without setting explicit sizes, but I might need to do it this way if I can't find a solution. – Flack Sep 15 '10 at 20:41
  • @Flack: Did you want it to scale to fill out some specific area in your control? – PhilB Sep 15 '10 at 20:58
  • @PhilB: Right now I think the text box will always be a constant size, but that may change in the future. I just wanted to avoid hard coding sizes as that seems like a winforms thing that should be avoided if possible in WPF. So basically, I want my StackPanel with the image and text box to be as wide as my WrapPanel that contains the two text blocks. – Flack Sep 15 '10 at 21:49
  • @Flack: Alright, I updated my answer to reflect that. I think this should work. – PhilB Sep 15 '10 at 22:05
  • Hey PhilB, it doesn't seem to work. Making the changes you suggested the text box still grows as I type. – Flack Sep 16 '10 at 18:51
  • Seems to work on my machine. The only other thing I could think of right now would be to set HorizontalAlignment="Stretch" on the TextBox element. – PhilB Sep 16 '10 at 19:17