WPF中的可扩展TextBlock

时间:2015-01-08 08:17:26

标签: c# wpf xaml

我需要文本块,可以在全文和修剪文本之间切换,如下图所示:

enter image description here

找不到类似的东西。

Expander就是这样,但默认会显示修剪版和完整版(在标题中修剪,内容全部完整)。

我想写一些带有附加属性的东西,但是我需要绘制按钮,检查它是否需要按钮(文本没有修剪),崩溃和扩展逻辑 - 简而言之我感觉就像在发明在这里,有人应该这样做,我可能找不到它吗?

3 个答案:

答案 0 :(得分:3)

您可以使用TextBlock,只需添加一个按钮即可切换TextWrapping属性。

<TextBlock Text="{Binding Text}" TextWrapping="{Binding WrapMode}" />
<Button Command="{Binding ToggleWrapMode}" />

按钮的命令在TextWrapping.NoWrapTextWrapping.Wrap之间切换。另外,请确保设置文本块(或其容器)的高度,以便以您想要的大小进行换行。

<强>更新 为了确定您是否需要显示该按钮,可以将WrapMode初始化为NoWrap并检查ActualHeight的{​​{1}}是否高于您的阈值定义。如果它更高 - 您将限制放在TextBlock的{​​{1}}上,否则您只需隐藏按钮。

我发现这种方法非常混乱(可能会导致屏幕闪烁),我会尝试更聪明地思考。

更新2: 正如Sinatr在命令中所建议的,this是一种更好的方式来了解你的文本是否需要包装。

答案 1 :(得分:2)

我做一个用户控制来处理这个案子。应该很容易......我已经ContentControl快速制作了这个,但可以轻松扩展以满足您的需求:

<ControlTemplate x:Key="MyControl" TargetType="ContentControl">
  <StackPanel>
    <Expander x:Name="ExpanderControl" IsExpanded="True"/>
    <TextBlock x:Name="MyTextBlock" TextTrimming="CharacterEllipsis" TextWrapping="Wrap" Text="Lorem ipsum dolor sit amet, consectetur adipiscing elit. Donec ex est, hendrerit a ante nec, molestie aliquet nunc. Mauris est mi, aliquam nec nulla id, placerat vulputate est. Nulla tristique elit eu sapien ultrices fringilla. Nulla ac dictum lorem, ac mattis elit. Sed augue arcu, bibendum nec mauris nec, volutpat pulvinar lacus. Mauris et volutpat nibh, eu luctus leo. Pellentesque non dapibus nisi.
Quisque in nulla eu purus sagittis bibendum. Pellentesque orci ipsum, porttitor vitae risus at, faucibus pellentesque justo. Aenean ut nibh pharetra orci euismod vehicula. Aenean commodo vestibulum placerat. Nam condimentum dictum purus nec suscipit. Duis semper ligula massa, in pretium diam scelerisque tincidunt. Vivamus placerat porttitor orci et finibus.
Aenean ut purus eu mi venenatis dapibus id vel urna. Donec enim odio, molestie sed pharetra vel, blandit non purus. Sed in leo eget felis suscipit consectetur. Suspendisse sagittis, sapien ac iaculis venenatis, velit purus viverra turpis, vitae suscipit mi odio pellentesque velit. Proin pulvinar sem consequat nunc varius semper. Maecenas vitae nisl quis risus auctor suscipit. Aenean libero tortor, placerat non ex et, gravida efficitur sem. Aliquam volutpat mauris fermentum, rhoncus arcu et, finibus tortor.
Praesent sit amet pretium risus. Quisque bibendum nibh vel risus rhoncus eleifend. Nunc in eros sit amet neque euismod laoreet. Aliquam dictum ac magna quis interdum. Lorem ipsum dolor sit amet, consectetur adipiscing elit. Duis varius diam dolor, mollis tristique nisl malesuada ac. Nulla sed vehicula sapien. Vestibulum venenatis lobortis sodales. Aliquam rhoncus metus at velit accumsan, at fringilla sapien condimentum. Aliquam erat volutpat. Aenean iaculis mi augue, quis bibendum nibh suscipit ut. Nam commodo, arcu et gravida accumsan, magna diam rhoncus ante, quis posuere nibh tortor nec ligula. Quisque id metus lacus. Quisque ac magna vel ligula commodo tempor. Nam scelerisque fringilla commodo. Curabitur volutpat libero ac metus aliquam, in egestas ipsum luctus.
Ut fringilla lacinia efficitur. Nulla odio tortor, eleifend sed porttitor ut, accumsan sed nunc. Morbi malesuada nisl in lobortis auctor. Nam suscipit neque ac neque blandit dictum. Duis pulvinar commodo enim eget laoreet. In sodales arcu nisl, sit amet posuere orci blandit nec. Nullam a dapibus est, lacinia maximus ante. Mauris rutrum ex nunc, non vehicula orci volutpat vehicula. Praesent mattis tortor non odio molestie, sit amet congue urna sollicitudin. Sed lobortis est et mauris suscipit mattis. Maecenas porttitor elit nec nulla pulvinar, nec porttitor odio placerat. Vivamus maximus lobortis erat a fringilla. Sed vitae hendrerit tortor." />
  </StackPanel>
  <ControlTemplate.Triggers>
    <Trigger SourceName="ExpanderControl" Property="IsExpanded" Value="False">
      <Trigger.Setters>
        <Setter TargetName="MyTextBlock" Property="Height" Value="100"/>
      </Trigger.Setters>
    </Trigger>
  </ControlTemplate.Triggers>
</ControlTemplate>

并使用它:

<ContentControl Template="{StaticResource MyControl}"/>

结果,扩展:

enter image description here

并签约:

enter image description here

当然,您需要根据自己的需要进行设计。可以(并且应该)使属性具有在UserControl中定义的文本而不是模板中所定义的文本,所需的合同高度等。

检查它是否真的需要一个按钮需要一些代码隐藏(检查HeightActualHeight是否会被FormattedText想到,但为了更好的方式,您最好创建一个TextBlock对象使用ActualHeight的字体,应用相同的文字并检查它的高度是否为控件的{{1}} ...我将它放在附件上依赖属性)。

答案 2 :(得分:0)

我结合了两个给定答案的想法并得到了非常愉快的结果,希望有人会觉得它很有用。 基本的想法是,我使用空Expander切换TextWlock的TextWrapping。 它只需要在一个地方使用C#代码 - 要知道TextBlock当前是否正在修剪文本,我已经从https://stackoverflow.com/a/25436070/212121借用了代码

<ControlTemplate x:Key="ExpandableTextBlock" TargetType="ContentControl">
        <Grid Focusable="False" Background="Transparent" Margin="4" VerticalAlignment="Center">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="*" />
                <ColumnDefinition x:Name="ExpandButtonColumnDefinition">
                    <ColumnDefinition.Style>
                        <Style TargetType="{x:Type ColumnDefinition}">
                            <Setter Property="Width" Value="50" />
                            <Style.Triggers>
                                <MultiDataTrigger>
                                    <MultiDataTrigger.Conditions>
                                        <Condition Binding="{Binding ElementName=TextBlock, Path=(wpfApplication8:TextBlockService.IsTextTrimmed)}" Value="False" />
                                        <Condition Binding="{Binding ElementName=TextBlock, Path=TextWrapping}" Value="NoWrap" />
                                    </MultiDataTrigger.Conditions>
                                    <MultiDataTrigger.Setters>
                                        <Setter Property="Width" Value="0" />
                                    </MultiDataTrigger.Setters>
                                </MultiDataTrigger>                                 
                            </Style.Triggers>
                        </Style>
                    </ColumnDefinition.Style>
                </ColumnDefinition>
            </Grid.ColumnDefinitions>
            <StackPanel x:Name="ViewPort" Orientation="Vertical" Margin="1" VerticalAlignment="Center" Grid.Column="0">
                <TextBlock x:Name="TextBlock" TextTrimming="CharacterEllipsis" Text="{TemplateBinding Content}" />                  
            </StackPanel>
            <Expander Grid.Column="1" x:Name="TextExpander" />                  
        </Grid>
        <ControlTemplate.Triggers>
            <Trigger SourceName="TextExpander" Property="IsExpanded" Value="True">
                <Setter TargetName="TextBlock" Property="TextWrapping" Value="Wrap" />
            </Trigger>
            <Trigger SourceName="TextExpander" Property="IsExpanded" Value="False">
                <Setter TargetName="TextBlock" Property="TextWrapping" Value="NoWrap" />
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>