Gerharddc
Gerharddc

Reputation: 4089

WPF TextBox getting cut off

For some strange reason my WPF textbox which is embedded in a scroll viewer get abruptly cut off like in the image below after I have added a lot of text to it. Is there some limit or something that is reached that I can make larger or something?

enter image description here

I do not receive any error messages.

Here is the relevant Xaml:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Button x:Name="Slice_Button" Content="Slice" HorizontalAlignment="Left" Margin="106,0,0,0" VerticalAlignment="Top" Click="Slice_Button_Click" Height="87" Background="#FF0D5B1E"/>
        <Button x:Name="CancelButton" Content="Cancel" HorizontalAlignment="Left" Margin="232,0,0,0" VerticalAlignment="Top" Height="87" Click="Button_Click_1" Background="#FFC70E0E"/>
        <ScrollViewer x:Name="Scroller" HorizontalAlignment="Left" Height="505" Margin="10,92,0,0" VerticalAlignment="Top" Width="436">
            <TextBox x:Name="OutBox" TextWrapping="Wrap" Text="Output will be displayed here" IsReadOnly="True" Margin="2"/>
        </ScrollViewer>

    </Grid>

Here is the C# I use to add the text:

main.DispatchInvoke(() =>
            {
                main.OutBox.Text += newText;
                main.Scroller.ScrollToVerticalOffset(main.Scroller.ScrollableHeight);
                main.Scroller.UpdateLayout();
            });

Upvotes: 4

Views: 3365

Answers (1)

Viv
Viv

Reputation: 17398

Second Update:

Ok so I decided to get the windows phone kit and try this out.

TextBox as the OP mentioned just wouldn't scroll. Hence I decided to look at it's default ControlTemplate

This is the stripped out ControlTemplate from vs2012 with windows phone 8 sdk for TextBox:

<ControlTemplate TargetType="TextBox">
  <Grid Background="Transparent">
    <!--  VisualState Groups for abt 100 lines  -->
    <Border x:Name="MainBorder"
            Margin="{StaticResource PhoneTouchTargetOverhang}"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}" />
    <Border x:Name="ReadonlyBorder"
            Margin="{StaticResource PhoneTouchTargetOverhang}"
            Background="Transparent"
            BorderBrush="{StaticResource PhoneDisabledBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Visibility="Collapsed" />
    <Border Margin="{StaticResource PhoneTouchTargetOverhang}"
            Background="Transparent"
            BorderBrush="Transparent"
            BorderThickness="{TemplateBinding BorderThickness}">
      <ContentControl x:Name="ContentElement"
                      Margin="{StaticResource PhoneTextBoxInnerMargin}"
                      HorizontalContentAlignment="Stretch"
                      VerticalContentAlignment="Stretch"
                      BorderThickness="0"
                      Padding="{TemplateBinding Padding}" />
    </Border>
  </Grid>
</ControlTemplate>

No ScrollViewer just a ContentControl. The following is from vs2012 for a desktop app TextBox

<ControlTemplate TargetType="{x:Type TextBox}">
  <Border x:Name="border"
          Background="{TemplateBinding Background}"
          BorderBrush="{TemplateBinding BorderBrush}"
          BorderThickness="{TemplateBinding BorderThickness}"
          SnapsToDevicePixels="True">
    <ScrollViewer x:Name="PART_ContentHost"
                  Focusable="False"
                  HorizontalScrollBarVisibility="Hidden"
                  VerticalScrollBarVisibility="Hidden" />
  </Border>

Also verified this with Snoop by copying the phone template to my desktop app and same behavior.

Not sure abt the reasoning for why it doesn't have a ScrollViewer, but adding one in the ControlTemplate sorts the issue out.

Solution:

Full Style for TextBox with ScrollViewer (Added within "App.xaml" -> <Application.Resources></Application.Resources>

<Style x:Key="TextBoxStyle1"
       TargetType="TextBox">
  <Setter Property="FontFamily"
          Value="{StaticResource PhoneFontFamilyNormal}" />
  <Setter Property="FontSize"
          Value="{StaticResource PhoneFontSizeMediumLarge}" />
  <Setter Property="Background"
          Value="{StaticResource PhoneTextBoxBrush}" />
  <Setter Property="Foreground"
          Value="{StaticResource PhoneTextBoxForegroundBrush}" />
  <Setter Property="BorderBrush"
          Value="{StaticResource PhoneTextBoxBrush}" />
  <Setter Property="SelectionBackground"
          Value="{StaticResource PhoneAccentBrush}" />
  <Setter Property="SelectionForeground"
          Value="{StaticResource PhoneTextBoxSelectionForegroundBrush}" />
  <Setter Property="BorderThickness"
          Value="{StaticResource PhoneBorderThickness}" />
  <Setter Property="Padding"
          Value="2" />
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="TextBox">
        <Grid Background="Transparent">
          <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates">
              <VisualState x:Name="Normal" />
              <VisualState x:Name="MouseOver" />
              <VisualState x:Name="Disabled">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MainBorder"
                                                 Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="Transparent" />
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MainBorder"
                                                 Storyboard.TargetProperty="BorderBrush">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneDisabledBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
                                                 Storyboard.TargetProperty="Foreground">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneDisabledBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="ReadOnly">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MainBorder"
                                                 Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame KeyTime="0">
                      <DiscreteObjectKeyFrame.Value>
                        <Visibility>Collapsed</Visibility>
                      </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ReadonlyBorder"
                                                 Storyboard.TargetProperty="Visibility">
                    <DiscreteObjectKeyFrame KeyTime="0">
                      <DiscreteObjectKeyFrame.Value>
                        <Visibility>Visible</Visibility>
                      </DiscreteObjectKeyFrame.Value>
                    </DiscreteObjectKeyFrame>
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ReadonlyBorder"
                                                 Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneTextBoxBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ReadonlyBorder"
                                                 Storyboard.TargetProperty="BorderBrush">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneTextBoxBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement"
                                                 Storyboard.TargetProperty="Foreground">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneTextBoxReadOnlyBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
            </VisualStateGroup>
            <VisualStateGroup x:Name="FocusStates">
              <VisualState x:Name="Focused">
                <Storyboard>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MainBorder"
                                                 Storyboard.TargetProperty="Background">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneTextBoxEditBackgroundBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                  <ObjectAnimationUsingKeyFrames Storyboard.TargetName="MainBorder"
                                                 Storyboard.TargetProperty="BorderBrush">
                    <DiscreteObjectKeyFrame KeyTime="0"
                                            Value="{StaticResource PhoneTextBoxEditBorderBrush}" />
                  </ObjectAnimationUsingKeyFrames>
                </Storyboard>
              </VisualState>
              <VisualState x:Name="Unfocused" />
            </VisualStateGroup>
          </VisualStateManager.VisualStateGroups>
          <Border x:Name="MainBorder"
                  Margin="{StaticResource PhoneTouchTargetOverhang}"
                  Background="{TemplateBinding Background}"
                  BorderBrush="{TemplateBinding BorderBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}" />
          <Border x:Name="ReadonlyBorder"
                  Margin="{StaticResource PhoneTouchTargetOverhang}"
                  Background="Transparent"
                  BorderBrush="{StaticResource PhoneDisabledBrush}"
                  BorderThickness="{TemplateBinding BorderThickness}"
                  Visibility="Collapsed" />
          <Border Margin="{StaticResource PhoneTouchTargetOverhang}"
                  Background="Transparent"
                  BorderBrush="Transparent"
                  BorderThickness="{TemplateBinding BorderThickness}">
            <ScrollViewer>
              <ContentControl x:Name="ContentElement"
                              Margin="{StaticResource PhoneTextBoxInnerMargin}"
                              HorizontalContentAlignment="Stretch"
                              VerticalContentAlignment="Stretch"
                              BorderThickness="0"
                              Padding="{TemplateBinding Padding}" />
            </ScrollViewer>
          </Border>
        </Grid>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

usage:

<Grid x:Name="ContentPanel"
      Grid.Row="1"
      Margin="12,0,12,0">
  <Grid.RowDefinitions>
    <RowDefinition Height="Auto" />
    <RowDefinition Height="*" />
  </Grid.RowDefinitions>
  <StackPanel Grid.Row="0"
              HorizontalAlignment="Center"
              Orientation="Horizontal">
    <Button x:Name="Slice_Button"
            Margin="10 0"
            Background="#FF0D5B1E"
            Content="Slice" />
    <Button x:Name="CancelButton"
            Margin="10 0"
            Background="#FFC70E0E"
            Content="Cancel" />
  </StackPanel>
  <TextBox x:Name="OutBox"
           Grid.Row="1"
           Margin="10"
           IsReadOnly="True"
           Style="{StaticResource TextBoxStyle1}"
           Text="Output will be displayed here"
           TextWrapping="Wrap" />
</Grid>

Do note just wrapping the TextBox in a ScrollViewer scroll's the entire control than just the content within it which might not be very appealing from a UX POV

Download Link to Sample Project With above fix: DropBox

Upvotes: 3

Related Questions