文本框文本修剪。

25

我想在一个TextBox(不是TextBlock)上应用TextTrimming选项。

编译器告诉我TextTrimming选项不是Textbox的有效属性。

在做一个复杂控件之前,我想知道是否已经存在内置函数(或更聪明的方法)允许您这样做?

编辑:最终我想要的是一个修剪的TextBox(完整内容将显示在工具提示中),但当用户选择TextBox(进入“编辑模式”)时,完整内容将被显示(而不是修剪的),因此用户将能够修改完整文本。当TextBox失去焦点时(回到“查看模式”),内容将再次被修剪。

谢谢


如果您正在使用 MVVM,您可以修剪存储在属性中的值。在属性更改时,UI 上的值也会更新。 - Akanksha Gaur
@DDzire:我同意我可以这样做,但我认为这实际上是一种显示行为,我不想每次处理这种显示时都在我的视图模型中放置一些修剪逻辑。 - Guillaume
5个回答

48

尝试使用以下样式(我已添加背景颜色以使更改更加明显):

    <Style TargetType="TextBox">
      <Setter Property="Background" Value="Yellow" />
      <Style.Triggers>
        <DataTrigger Binding="{Binding IsKeyboardFocused, RelativeSource={RelativeSource Self}}" Value="false">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="TextBox">
                <TextBlock Text="{TemplateBinding Text}"  TextTrimming="CharacterEllipsis" Background="Red" />
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </DataTrigger>
      </Style.Triggers>
    </Style>

3

Dan Puzey的回答非常好,但我想添加更多内容,以便TextBlock的样式看起来像一个TextBox

这是我想出的XAML样式:

<Style TargetType="TextBox">
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsKeyboardFocused, RelativeSource={RelativeSource Self}}" Value="False">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Border BorderThickness="1" CornerRadius="1">
                            <Border.BorderBrush>
                                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                                    <GradientStop Color="#FFABADB3" Offset="0"/>
                                    <GradientStop Color="#FFABADB3" Offset="0.044"/>
                                    <GradientStop Color="#FFE2E3EA" Offset="0.060"/>
                                    <GradientStop Color="#FFE3E9EF" Offset="1"/>
                                </LinearGradientBrush>
                            </Border.BorderBrush>
                            <TextBlock Padding="4,2,0,0" Text="{TemplateBinding Text}" TextTrimming="CharacterEllipsis"/>
                        </Border>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </DataTrigger>
    </Style.Triggers>
</Style>

这是控件没有键盘焦点时的外观:

TextBlock - No Keyboard Focus

这是控件获得键盘焦点后的外观:

TextBox - With Keyboard Focus


1

enter image description here

enter image description here

我会使用不同的控件模板:当文本框没有焦点时,使用修剪模板,而当文本框有焦点时,使用常规模板以允许选择文本。需要替换文本框控件模板。

 <ControlTemplate TargetType="{x:Type TextBox}"
                 x:Key="ControlTemplateTextBoxNormal">
    <Border Background="{TemplateBinding Background}"
            BorderThickness="{TemplateBinding BorderThickness}"
            BorderBrush="{TemplateBinding BorderBrush}">
        <Grid>
            <Border x:Name="ErrorElement"
                    Visibility="Collapsed"
                    BorderThickness="1.25"
                    BorderBrush="{StaticResource BrushError}">
                <Grid>
                    <Polygon x:Name="toolTipCorner"
                             Panel.ZIndex="2"
                             Margin="-1"
                             Points="9,9 9,0 0,0"
                             Fill="{StaticResource BrushError}"
                             HorizontalAlignment="Right"
                             VerticalAlignment="Top">
                        <Polygon.ToolTip>
                            <ToolTip Style="{StaticResource ToolTipStyleError}"
                                     Content="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" />
                        </Polygon.ToolTip>
                    </Polygon>
                </Grid>
            </Border>
            <ScrollViewer x:Name="PART_ContentHost"
                          Padding="{TemplateBinding Padding}"
                          BorderThickness="0"
                          IsTabStop="False"
                          HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                          VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                          TextElement.Foreground="{TemplateBinding Foreground}" />
            <TextBlock Text="{Binding Path=(behaviors:TextBoxBehaviors.WatermarkText), RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}"
                       IsHitTestVisible="False"
                       Visibility="Collapsed"
                       HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                       VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                       Margin="{TemplateBinding Padding}"
                       Foreground="Gray"
                       x:Name="watermark" />
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsFocused"
                 Value="False">
            <Setter Property="Visibility"
                    TargetName="watermark"
                    Value="Visible" />
        </Trigger>
        <Trigger Property="Validation.HasError"
                 Value="True">
            <Setter Property="Visibility"
                    TargetName="ErrorElement"
                    Value="Visible" />
        </Trigger>
        <!--<Trigger Property="behaviors:TextBoxBehaviors.WatermarkText"
                             Value="True">
                        <Setter Property="Visibility"
                                TargetName="ErrorElement"
                                Value="Visible" />
                    </Trigger>-->

    </ControlTemplate.Triggers>
</ControlTemplate>
 <Style TargetType="{x:Type TextBox}"
       BasedOn="{StaticResource {x:Type TextBox}}"
       x:Key="TextBoxStyleTrimming">
    <Setter Property="BorderThickness"
            Value="1" />
    <Setter Property="Validation.ErrorTemplate"
            Value="{x:Null}" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Border Background="{TemplateBinding Background}"
                        BorderThickness="{TemplateBinding BorderThickness}"
                        BorderBrush="{TemplateBinding BorderBrush}">
                    <Grid>
                        <Border x:Name="ErrorElement"
                                Visibility="Collapsed"
                                BorderThickness="1.25"
                                BorderBrush="{StaticResource BrushError}">
                            <Grid>
                                <Polygon x:Name="toolTipCorner"
                                         Panel.ZIndex="2"
                                         Margin="-1"
                                         Points="9,9 9,0 0,0"
                                         Fill="{StaticResource BrushError}"
                                         HorizontalAlignment="Right"
                                         VerticalAlignment="Top">
                                    <Polygon.ToolTip>
                                        <ToolTip Style="{StaticResource ToolTipStyleError}"
                                                 Content="{Binding (Validation.Errors)[0].ErrorContent, RelativeSource={RelativeSource TemplatedParent}}" />
                                    </Polygon.ToolTip>
                                </Polygon>
                            </Grid>
                        </Border>
                        <TextBlock Padding="{TemplateBinding Padding}"
                                   Text="{TemplateBinding Text}"
                                   TextTrimming="CharacterEllipsis"
                                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                   VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                   TextElement.Foreground="{TemplateBinding Foreground}" />
                        <TextBlock Text="{Binding Path=(behaviors:TextBoxBehaviors.WatermarkText), RelativeSource={RelativeSource FindAncestor,AncestorType={x:Type TextBox}}}"
                                   IsHitTestVisible="False"
                                   Visibility="Collapsed"
                                   HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                   VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                   Margin="{TemplateBinding Padding}"
                                   Foreground="Gray"
                                   x:Name="watermark" />
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsFocused"
                             Value="False">
                        <Setter Property="Visibility"
                                TargetName="watermark"
                                Value="Visible" />
                    </Trigger>
                    <Trigger Property="Validation.HasError"
                             Value="True">
                        <Setter Property="Visibility"
                                TargetName="ErrorElement"
                                Value="Visible" />
                    </Trigger>

                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsKeyboardFocused"
                 Value="True">
            <Setter Property="Template"
                    Value="{StaticResource ControlTemplateTextBoxNormal}" />
        </Trigger>
    </Style.Triggers>
</Style>

0

您可以为您的TextBox创建一个控件模板,当它获得焦点时显示常规编辑器,而在失去焦点时则显示带有修剪的TextBlock


我本来就想这么做,但我想知道是否已经有内置的东西存在。如果今天结束之前没有人提出更聪明的方法,我会接受你的答案。 - Guillaume

0

我想你要找的是这个

<TextBox Text="{Binding Path=String, Converter={StaticResource StringConverter}, ConverterParameter=Trim:Argument:AnotherArgument}" /> 

希望能对你有所帮助 :)

它将调用 trim 函数并传递任何参数(如果需要的话)。 你也可以使用 split 并将分隔符作为参数传递。

你可以在 Binding.Converter 这里 找到更多信息。


它不会按照我想要的方式工作。在你的情况下,它将正确显示,但我将不再拥有适当的编辑模式(用户将无法访问修剪部分)。 - Guillaume
你究竟想要实现什么目标呢? - Akanksha Gaur
将转换器应用于工具提示 Den 上,将其模板更改为文本块。可以在数据上应用 TextTrimming。 - Akanksha Gaur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接