2015-09-07 2 views
1

Рассмотрим следующий образец XAML.WPF: ScrollViewer & Grid - отключить изменение размера TexBox

  1. У меня есть ScrollViewer. В случае, если окна слишком малы для сетки, прокрутки будут видны.
  2. В ScrollViewer находится сетка. Все элементы в сетке должны растягиваться до ширины столбца сетки.
  3. Теперь есть текстовые поля (с очень длинным текстом).

Моя проблема заключается в том, что текстовые поля будут становиться все больше и больше, если текст становится больше. Но я просто хочу, чтобы текстовые поля соответствовали пространству сетки.

Как я могу отключить изменение размера текстового поля с помощью большого текста внутри?

<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition Height="30" /> 
      <RowDefinition Height="30" /> 
      <RowDefinition Height="26" /> 
      <RowDefinition Height="26" /> 
      <RowDefinition Height="26" /> 
      <RowDefinition Height="26" /> 
      <RowDefinition Height="26" /> 
      <RowDefinition Height="26" /> 
      <RowDefinition Height="10*" /> 
     </Grid.RowDefinitions> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="100" /> 
      <ColumnDefinition Width="*" MinWidth="130" /> 
      <ColumnDefinition Width="130" /> 
     </Grid.ColumnDefinitions> 

     <Label VerticalAlignment="Center" HorizontalAlignment="Left" Content="Label 1" Grid.Column="0" Grid.Row="0"/> 
     <TextBox x:Name="Tbox1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="asfas fasd fasdf asdf asdf asdf asdf asf safasdf asdf asdf fasasd fas f" TextWrapping="Wrap" Height="22" Grid.Column="1" Grid.Row="0" /> 

     <Label VerticalAlignment="Center" HorizontalAlignment="Left" Content="Label 2" Grid.Column="0" Grid.Row="1"/> 
     <TextBox x:Name="Tbox2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="asfas fasd fasdf asdf asdf asdf asdf asf safasdf asdf asdf fasasd fas f" TextWrapping="Wrap" Height="22" Grid.Column="1" Grid.Row="1" /> 

    </Grid> 
</ScrollViewer> 
+0

Не уверен, что понимаете свою проблему, но если ваше текстовое поле должно всегда соответствовать ширине исправления, почему бы вам не установить его ширину в нужное значение? –

ответ

4

Вы должны епз что TextBox не будет изменять размер сетки.

Самый простой способ - разместить текстовое поле в таком контейнере , который игнорирует размер своих детей, например. Canvas. Вам также необходимо установить размер текстового поля, привязывая его к ширине столбца.

<ScrollViewer HorizontalScrollBarVisibility="Auto"> 
    <Grid> 
     <Grid.ColumnDefinitions> 
      <ColumnDefinition Width="100" /> 
      <ColumnDefinition x:Name="MiddleColumn" Width="*" MinWidth="130" /> 
      <ColumnDefinition Width="130" /> 
     </Grid.ColumnDefinitions> 

     <Canvas Grid.Column="1"> 
      <TextBox Width="{Binding ActualWidth, ElementName=MiddleColumn}"/> 
     </Canvas> 

    </Grid> 
</ScrollViewer> 

Однако, обратите внимание, что холст также ingores высоты TextBox, и если текст завернут, строка не изменяется. Вы можете обойти его с помощью высоты холста DataBinding в TextBox.ActualHeight. Вы можете инкапсулировать этот макет привязки в многоразовый стиль:

<ContentControl Grid.Column="1" Style="{StaticResource IgnoreContentWidthStyle}"> 
    <TextBox Text="asfasdf asdfad sfa sdf" TextWrapping="Wrap"/> 
</ContentControl> 

<Style x:Key="IgnoreContentWidthStyle" TargetType="ContentControl"> 
    <Setter Property="Template"> 
     <Setter.Value> 
      <ControlTemplate TargetType="ContentControl"> 
       <Canvas Height="{Binding ActualHeight, ElementName=PART_Content}"> 
        <ContentPresenter x:Name="PART_Content" 
             Content="{TemplateBinding Content}" 
             Width="{TemplateBinding ActualWidth}"/> 
       </Canvas> 
      </ControlTemplate> 
     </Setter.Value> 
    </Setter> 
</Style> 

Alternativelly, вы можете создать пользовательский элемент, производный от Panel, или декоратора, который перекроет MeasureOverride и ArrangeChildren и поместить текстовое поле внутри. Такой подход дает вам лучшую производительность, поскольку вы избегаете привязки макета.

1

Ну, я думаю, у вас есть 2 варианта, чтобы остановить текстовые поля становится все больше:

  1. Отключить горизонтальные полосы прокрутки
  2. Bind ширину текстового поля Макс к другому элементу, как это:

    <Grid Grid.Column="1" Name="grdWidth"/> 
    
        <Label VerticalAlignment="Center" HorizontalAlignment="Left" Content="Label 1" Grid.Column="0" Grid.Row="0"/> 
        <TextBox x:Name="Tbox1" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="asfas fasd fasdf asdf asdf asdf asdf asf safasdf asdf asdf fasasd fas f" TextWrapping="Wrap" 
        MaxWidth="{Binding ActualWidth, ElementName=grdWidth}" Height="22" Grid.Column="1" Grid.Row="0" /> 
    
        <Label VerticalAlignment="Center" HorizontalAlignment="Left" Content="Label 2" Grid.Column="0" Grid.Row="1"/> 
        <TextBox x:Name="Tbox2" VerticalAlignment="Center" HorizontalAlignment="Stretch" Text="asfas fasd fasdf asdf asdf asdf asdf asf safasdf asdf asdf fasasd fas f" TextWrapping="Wrap" Height="22" Grid.Column="1" 
        MaxWidth="{Binding ActualWidth, ElementName=grdWidth}" 
        Grid.Row="1" /> 
    
    </Grid> 
    

Я бы лично пойти с первым вариантом

+0

если вы databind maxwidth и измените размер окна на меньший размер, то появится полоса прокрутки – Liero

+0

Я согласен. OP сказал: «Моя проблема в том, что текстовые поля будут становиться все больше и больше, если текст становится все больше, но я просто хочу, чтобы текстовые поля соответствовали пространству сетки». Я лично не думаю, что наличие сетки, которая не подходит по горизонтали, - это хорошее мнение, но это то, чего хочет OP, я считаю – netaholic