Остановка WPF TextBox от увеличения текста

Я пытаюсь изменить свой простой элемент управления, чтобы текстовое поле не увеличивалось, когда пользователь вводит длинный текст. Я рассмотрел некоторые решения, опубликованные здесь, в Stackoverflow, которые предлагают использовать сетку и невидимую границу и привязать ширину текстового поля к фактической ширине границы, но я не могу заставить его работать в моей настройке.

Вот xaml моего элемента управления:

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

Любые идеи? Мне нужно, чтобы zoom.png отображался «внутри» текстового поля, поэтому я использую горизонтальную панель стека и просто размещаю изображение и текстовое поле рядом, окруженные одной и той же границей.

Есть ли способ остановить автоматическое увеличение моего текстового поля по мере ввода текста?

Спасибо.

ОБНОВЛЕНИЕ:

Ниже приведен xaml, который я тестирую.

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

Я просто добавляю свой пользовательский элемент управления в MainRegion окна.


person Flack    schedule 15.09.2010    source источник


Ответы (6)


Я сделал еще несколько поисков и нашел решение. Я использовал приведенную ниже сетку, чтобы заменить сетку в своем исходном сообщении, и теперь текстовое поле сохраняет свой первоначальный размер и не увеличивается автоматически при длительном вводе пользователем. Спасибо всем, кто заглянул в это.

      <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>
person Flack    schedule 20.09.2010
comment
Спасибо. Я попробовал это, и это сработало с одним недостатком для меня. Его нельзя использовать, если вы используете scrollviewer. Первоначально у меня был один, и происходило то, что текстовое поле росло, когда пользовательский интерфейс рос, но не уменьшался, когда пользовательский интерфейс уменьшался. - person famousKaneis; 01.06.2015
comment
@nameless Вы должны установить HorizontalScrollBarVisibility = "False" для вашего Scrollviewer, чтобы текстовое поле соответствовало ширине окна при его уменьшении. - person M463; 30.07.2015
comment
Это должно было быть исправлено в самом WPF, если это единственное реальное решение... (я сам пока не нашел ничего лучше, и мы в 2016 году...) - person Arwin; 16.03.2016
comment
На самом деле, я возвращаюсь к этому. Трюк с границей не нужен, если вы отключили HorizontalScrollBarVisibility для собственного ScrollViewer Grid или ListView. После того, как я это сделал, все пошло так, как я ожидал и надеялся. - person Arwin; 18.03.2016

Попробуйте поместить ScrollViewer.HorizontalScrollBarVisibility="Disabled" внутрь Grid.

person kostas    schedule 27.12.2010
comment
Это лучший ответ. - person Arwin; 18.03.2016

Назовите сетку как x:Name="grdTest" и попробуйте это

<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> 
person Kishore Kumar    schedule 16.09.2010
comment
Привет, Кишор. Я привязал ширину текстового поля к ширине сетки, и текстовое поле не увеличивается по мере ввода, но теперь, когда я помещаю пользовательский элемент управления в окно (например, добавляю его на панель переноса в окне), он всегда занимает всю ширина окна. Есть ли способ ограничить его шириной панели переноса, содержащей два текстовых блока? - person Flack; 16.09.2010
comment
Я обновил свой исходный пост, включив в него xaml, который я тестирую. - person Flack; 17.09.2010

Чтобы остановить рост, задайте явный размер для TextBox или поместите его в сетку с параметром HorizontalAlignment, установленным на растяжение.

Вариант 1:

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

Вариант 2:

<TextBox HorizontalAlignment="Stretch">THIS IS SOME TEXT</TextBox>
person rudigrobler    schedule 15.09.2010
comment
Можете ли вы опубликовать, как будет выглядеть xaml? Я попытался обернуть текстовое поле сеткой и установить для параметра HorizontalAlignment текстового поля значение Stretch, но это не предотвратило увеличение текстового поля по мере ввода текста. (Я также попытался установить для Grid HorizontalAlignment значение Stretch на случай, если я неправильно понял, но результат был таким же.) - person Flack; 16.09.2010

Чтобы масштабировать границу, содержащую текстовое поле, до ширины внешней панели стека, измените внутреннюю панель стека на сетку и установите левое поле в текстовом поле, чтобы оно не перекрывалось с изображением. Также установите горизонтальное выравнивание изображения по левому краю (если это то место, где вы этого хотите), иначе по умолчанию оно будет по центру границы.

        <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>
person PhilB    schedule 15.09.2010
comment
Спасибо. Я искал способ сделать это без указания явных размеров, но мне может понадобиться сделать это таким образом, если я не могу найти решение. - person Flack; 16.09.2010
comment
@Flack: Вы хотели, чтобы он масштабировался, чтобы заполнить какую-то определенную область под вашим контролем? - person PhilB; 16.09.2010
comment
@PhilB: Сейчас я думаю, что текстовое поле всегда будет иметь постоянный размер, но это может измениться в будущем. Я просто хотел избежать жестких размеров кода, так как это похоже на winforms, которого следует избегать, если это возможно в WPF. Итак, в основном, я хочу, чтобы моя StackPanel с изображением и текстовым полем была такой же ширины, как моя WrapPanel, содержащая два текстовых блока. - person Flack; 16.09.2010
comment
@Flack: Хорошо, я обновил свой ответ, чтобы отразить это. Я думаю, это должно сработать. - person PhilB; 16.09.2010
comment
Привет, PhilB, похоже, это не работает. Внося изменения, которые вы предложили, текстовое поле по-прежнему растет по мере ввода. - person Flack; 16.09.2010
comment
Кажется, работает на моей машине. Единственное, что я мог придумать прямо сейчас, это установить HorizontalAlignment=Stretch для элемента TextBox. - person PhilB; 16.09.2010

В этой статье показано решение для текстового поля, которое отображается в окне просмотра средства просмотра прокрутки (в дереве или списке). PART_MeasureTextBlock используется (привязанный к текстовому полю), чтобы определить доступный размер и установить его для текстового поля. Пожалуйста, загляните сюда и скажите, что вы об этом думаете: http://www.codeproject.com/Articles/802385/A-WPF-MVVM-In-Place-Edit-TextBox-Control

person user3313608    schedule 30.07.2014