Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TextBox with the same clipping as TextBlock (TextBox Template)

The TextBlock element treats LineHeight nicely, allowing the text to display fully, without clipping. However, I want to change it to a TextBox to facilitate editing the text and this is where my trouble starts.

The TextBlock display the text like this:

Tall letters display beyond the hight of the TextBlock

The TextBox display the text like this:

Tall letters are being clipped!

I've tried to fiddle with the ClipToBounds and Clip properties, but it only clips within the element and will not expand beyond the borders.

The LineHeight property needs to be set low to regulate the gap between the lines so it's not an option to change.

I've also tried Padding, but it only does this

Padding, but text is still clipped

I'd go out of my way and listen on key presses and change the text accordingly if that's the only solution, but it seems like a lot of work and I don't think it'd be a good solution, so here's my condensed question:

How do I make TextBox not clip text the same way as TextBlock if it is at all possible?


Update Here's the styling code (what I currently have anyway) and where it's applied.
private static Style GetFontTextBlock()
{
    var style = new Style();
    style.Setters.Add(new Setter(TextBlock.LineStackingStrategyProperty, LineStackingStrategy.BlockLineHeight));
    style.Setters.Add(new Setter(TextBlock.IsHyphenationEnabledProperty, true));
    style.Setters.Add(new Setter(TextBlock.TextWrappingProperty, TextWrapping.Wrap));
    style.Setters.Add(new Setter(Control.BorderBrushProperty, null));
    return style;
}

public static Style GetHeadline()
{
    // ApplyFont sets the Control.FontFamilyProperty to Geogrotesque Condensed Regular.
    // It's a purchased font so I can't supply it, unfortunately
    var style = ApplyFont(new Style { BasedOn = GetFontTextBlock() });
    style.Setters.Add(new Setter(TextBlock.FontSizeProperty, 140));
    style.Setters.Add(new Setter(TextBlock.LineHeightProperty, 112));
    return style;
}

It's applied to this control within a UserControl

<Grid>
    ...
    <StackPanel>
        <TextBox Background="Cornsilk" Name="Headline" AcceptsReturn="True" />
    ...
    </StackPanel>
    ...
</Grid>


Update Based on Cadogis answer, the style setter code turned out to be as follows:
public static Style GetHeadline(Enums.Enums.SheetSizes size, object triggerTarget)
    [...]
    style.Setters.Add(new Setter(TextBox.TemplateProperty, XamlReader.Parse(
        // Breaks and indentation for readability
        @"<ControlTemplate TargetType='TextBox'
            xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation'>
            <DockPanel>
                <Decorator Name='PART_ContentHost' />
            </DockPanel>
        </ControlTemplate>")));
    return style;
}

Which produces the much desired result

TextBox with TextBlock clipping!

Thanks to both of you for helping me!

like image 438
Heki Avatar asked Jul 27 '15 07:07

Heki


2 Answers

I may be missing something here but when calling your textbox , you can set min and max values for height and width then just set them to auto e.g.

<TextBox Text="Test&#xA;test" Style="{StaticResource HeadlineFontTextBoxStyle}" 
AcceptsReturn="True" Height="Auto" MinHeight="24" MaxHeight="120" />

I should point out that using this in a stack panel will restrict the height be default, using a grid will give you the best results, as it will expand on the fly.

Obviously you don't want the control to expand indefinitely, so the max properties will reign it in if its getting too big, but "Auto" should allow it to size properly. Sorry if I've completely missed the point.


Template idea

Not sure if this is quite what you would be looking for but it's a modified template for a textbox to to render outside the border (it uses a decorator instead of a scrollviewer) - figured i should try to give an option that might work.

<UserControl x:Class="UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
    <Style x:Key="FontTextBoxStyle" TargetType="{x:Type TextBox}">
        <Setter Property="TextBlock.LineStackingStrategy" Value="BlockLineHeight"></Setter>
        <Setter Property="TextBlock.IsHyphenationEnabled" Value="True"></Setter>
        <Setter Property="TextBlock.TextWrapping" Value="Wrap"></Setter>
        <Setter Property="Control.BorderBrush" Value="{x:Null}"></Setter>
    </Style>
    <Style x:Key="HeadlineFontTextBoxStyle" TargetType="{x:Type TextBox}" >
    <Setter Property="TextBlock.LineHeight" Value="100"></Setter>
    <Setter Property="TextBlock.LineStackingStrategy" Value="BlockLineHeight"/>
    <Setter Property="FontSize" Value="140"></Setter>
    <Setter Property="AcceptsReturn" Value="True" />
    <Setter Property="Height" Value="Auto"/>
    <Setter Property="VerticalContentAlignment" Value="Top"/>
        <Setter Property="Template">
            <Setter.Value>
            <ControlTemplate TargetType="TextBox">
                    <DockPanel>                           
                        <Decorator Name="PART_ContentHost" />
                    </DockPanel>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</UserControl.Resources>
<Grid>
    <TextBox Text="Test&#xA;test" Style="{StaticResource HeadlineFontTextBoxStyle}" TextChanged="TextBox_TextChanged" />
</Grid>

For reference you might want to look at this from MSDN: https://msdn.microsoft.com/en-us/library/ms752068%28v=vs.85%29.aspx

like image 153
Cadogi Avatar answered Nov 13 '22 07:11

Cadogi


I tried your settings (rewritten in styles in xaml) and with the TextBlock, I see the same display as you. But with the TextBox, the letters are fully visible, nothing is clipped.

 <UserControl x:Class="WpfApplication2.UserControl2"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
  <UserControl.Resources>
    <Style x:Key="FontTextBoxStyle" TargetType="{x:Type TextBox}">
      <Setter Property="TextBlock.LineStackingStrategy" Value="BlockLineHeight"></Setter>
      <Setter Property="TextBlock.IsHyphenationEnabled" Value="True">  </Setter>
      <Setter Property="TextBlock.TextWrapping" Value="Wrap"></Setter>
      <Setter Property="Control.BorderBrush" Value="{x:Null}"></Setter>
    </Style>
    <Style x:Key="HeadlineFontTextBoxStyle" TargetType="{x:Type TextBox}" BasedOn="{StaticResource FontTextBoxStyle}">
      <Setter Property="TextBlock.LineHeight" Value="122"></Setter>
      <Setter Property="FontSize" Value="140"></Setter>
    </Style>
  </UserControl.Resources>
  <StackPanel>
    <TextBox Text="Testtest" Style="{StaticResource HeadlineFontTextBoxStyle}" />
  </StackPanel> 
 </UserControl>
like image 43
tabina Avatar answered Nov 13 '22 08:11

tabina