Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Wpf 从左开始修剪文本_Wpf_Silverlight_Xaml_Texttrimming - Fatal编程技术网

Wpf 从左开始修剪文本

Wpf 从左开始修剪文本,wpf,silverlight,xaml,texttrimming,Wpf,Silverlight,Xaml,Texttrimming,有没有办法将TextBlock上的文本修剪指定为从左侧开始 我已经成功完成了三个场景中的两个(第三个是我需要的场景): 定期修剪 <TextBlock VerticalAlignment="Center" Width="80" TextTrimming="WordEllipsis" Text="A very long text that requires trimming" /> // Result: "A very long te..."

有没有办法将
TextBlock
上的文本修剪指定为从左侧开始

我已经成功完成了三个场景中的两个(第三个是我需要的场景):

  • 定期修剪

    <TextBlock 
        VerticalAlignment="Center" 
        Width="80" 
        TextTrimming="WordEllipsis"
        Text="A very long text that requires trimming" />
    
    // Result: "A very long te..."
    

  • 有人知道这是否可能吗?谢谢

    你不能开箱即用,但我可以想到两件事:

    1) 为TextBlock创建一个名为LeftTrimmingText的附加属性。然后,您将设置此属性而不是文本属性。例如

      <TextBlock my:TextBlockHelper.LeftTrimmingText="A very long text that requires trimming." />
    
    
    
    附加属性将计算实际可以显示的字符数,然后相应地设置TextBlock的Text属性

    2) 创建自己的类来包装一个TextBlock,并添加自己的属性来处理所需的逻辑


    我认为第一个选项更容易。

    我不知道这是否是打字错误,但你错过了“期望结果”末尾的
    句号。我想你不会想要的。因为您知道应该显示多少个字符,所以只需获取整个字符串的子字符串并显示它即可。比如说,

    string origText = "A very long text that requires trimming.";
    
    //15 because the first three characters are replaced
    const int MAXCHARACTERS = 15;
    
    //MAXCHARACTERS - 1 because you don't want the full stop
    string sub = origText.SubString(origText.Length-MAXCHARACTERS, MAXCHARACTERS-1);
    
    string finalString = "..." + sub;
    textBlock.Text = finalString;
    

    如果您不知道在advanced中需要多少字符,则可以执行计算来确定它。在您的示例中,宽度为
    80
    会产生
    17
    个字符,如果宽度发生变化,您可以使用该比率

    如果不关心省略号,只想在文本被截断时看到文本的结尾而不是开头,可以将文本块包装到另一个容器中,并将其水平对齐设置为右侧。这将切断它就像你想要的,但没有省略

    <Grid>
        <TextBlock Text="Really long text to cutoff." HorizontalAlignment="Right"/>
    </Grid>
    

    这种风格就可以了。诀窍是重新定义标签的控件模板。然后将内容放入剪裁画布中,并与画布右侧对齐。内容的最小宽度是画布的宽度,因此,如果有足够的空间,则内容文本将左对齐,剪裁时将右对齐

    如果内容的宽度大于画布,则会触发省略号启用

    <Style x:Key="LeftEllipsesLabelStyle"
           TargetType="{x:Type Label}">
        <Setter Property="Foreground"
                Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="Padding"
                Value="5" />
        <Setter Property="HorizontalContentAlignment"
                Value="Left" />
        <Setter Property="VerticalContentAlignment"
                Value="Top" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Label}">
                    <Grid >
                        <Grid.Resources>
                            <LinearGradientBrush x:Key="HeaderBackgroundOpacityMask" StartPoint="0,0" EndPoint="1,0">
                                <GradientStop Color="Black"  Offset="0"/>
                                <GradientStop Color="Black" Offset="0.5"/>
                                <GradientStop Color="Transparent" Offset="1"/>
                            </LinearGradientBrush>
                        </Grid.Resources>
    
                        <Canvas x:Name="Canvas" 
                                ClipToBounds="True" 
                                DockPanel.Dock="Top"  
                                Height="{Binding ElementName=Content, Path=ActualHeight}">
    
                            <Border 
                                BorderBrush="{TemplateBinding BorderBrush}"
                                Canvas.Right="0"
                                Canvas.ZIndex="0"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                Padding="{TemplateBinding Padding}"
                                MinWidth="{Binding ElementName=Canvas, Path=ActualWidth}"
                                SnapsToDevicePixels="true"
                                x:Name="Content"
                            >
                                <ContentPresenter
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    Content="{Binding RelativeSource={RelativeSource AncestorType=Label}, Path=Content}"
                                    RecognizesAccessKey="True"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                >
                                    <ContentPresenter.Resources>
                                        <Style TargetType="TextBlock">
                                            <Setter Property="FontSize" Value="{Binding FontSize, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                            <Setter Property="FontWeight" Value="{Binding FontWeight, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                            <Setter Property="FontStyle" Value="{Binding FontStyle, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                            <Setter Property="FontFamily" Value="{Binding FontFamily, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                        </Style>
                                    </ContentPresenter.Resources>
    
                                </ContentPresenter>
                            </Border>
                            <Label 
                                x:Name="Ellipses" 
                                Canvas.Left="0" 
                                Canvas.ZIndex="10"
                                FontWeight="{TemplateBinding FontWeight}"
                                FontSize="{TemplateBinding FontSize}"
                                FontFamily="{TemplateBinding FontFamily}"
                                FontStyle="{TemplateBinding FontStyle}"
                                VerticalContentAlignment="Center" 
                                OpacityMask="{StaticResource HeaderBackgroundOpacityMask}" 
                                Background="{TemplateBinding Background}"
                                Foreground="RoyalBlue"
                                Height="{Binding ElementName=Content, Path=ActualHeight}" 
                                Content="...&#160;&#160;&#160;">
                                <Label.Resources>
                                    <Style TargetType="Label">
                                        <Style.Triggers>
                                            <DataTrigger Value="true">
                                                <DataTrigger.Binding>
                                                    <MultiBinding Converter="{StaticResource GteConverter}">
                                                        <Binding ElementName="Canvas" Path="ActualWidth"/>
                                                        <Binding ElementName="Content" Path="ActualWidth"/>
                                                    </MultiBinding>
                                                </DataTrigger.Binding>
                                                <Setter Property="Visibility" Value="Hidden"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Label.Resources>
    
                            </Label>
                        </Canvas>
    
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled"
                                 Value="false">
                            <Setter Property="Foreground"
                                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    它在这里工作


    不幸的是,第一个选择并不容易。Silverlight不公开文本呈现/度量API。您所能做的最好的事情就是检测何时发生修剪。请参阅这篇博文:ColinE:MeasurementAPI就是TextBlock本身。基本上,您可以在代码中创建一个新的临时文本块,并不断添加字符,直到实际宽度大于您想要的。temp TextBlock不需要渲染,甚至不需要在视觉树中渲染。谢谢,@RobSiklos和ColinEDon不要忘记-字符宽度取决于字体是的,我假设OP事先知道字体。如果不是,则OP可以使用此方法根据字体确定文本宽度:“在您的示例中,80个字符的宽度将产生17个字符,如果宽度发生变化,您可以使用该比率。”-每个字符可以(并且通常有)其各自的宽度。使用一个示例字符串的比率不会产生任何精确的结果。我认为您需要TextTrimming=“CharacterEllipsis”而不是WordEllipsis。出于某种原因,标签的不透明掩码对我来说无法正常工作,但我通过使用Background属性实现了我想要的效果-整洁的解决方案,谢谢!看起来是最干净的解决方案。虽然代码对我不起作用,但它根本不显示任何文本。你有关于如何使用它的示例吗?我是WPF和XAML的新手。我收到一个关于未定义命名空间前缀“c”以及未找到类型“c:GteConverter”的错误。我想我不是没有把所有的东西都放在正确的位置/文件里,就是缺少了一些东西。嗨,克里斯。我已经一年多没有使用XAML了,现在它对我来说又开始像黑魔法了。但是,上面的代码假定您知道如何处理XAML名称空间。如果不是的话,阅读可能会有所帮助。如果你不能以尽可能完整的信息开始另一个问题,那么最新的人可能会提供帮助。啊,无论如何,谢谢你的原始帖子。我想我会弄明白的。VisualStudio如何显示错误,而这些错误在实际编译代码时可能会消失,这让我感到厌烦。
    <Grid>
        <TextBlock Text="Really long text to cutoff." HorizontalAlignment="Right"/>
    </Grid>
    
    <Style x:Key="LeftEllipsesLabelStyle"
           TargetType="{x:Type Label}">
        <Setter Property="Foreground"
                Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
        <Setter Property="Background"
                Value="Transparent" />
        <Setter Property="Padding"
                Value="5" />
        <Setter Property="HorizontalContentAlignment"
                Value="Left" />
        <Setter Property="VerticalContentAlignment"
                Value="Top" />
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Label}">
                    <Grid >
                        <Grid.Resources>
                            <LinearGradientBrush x:Key="HeaderBackgroundOpacityMask" StartPoint="0,0" EndPoint="1,0">
                                <GradientStop Color="Black"  Offset="0"/>
                                <GradientStop Color="Black" Offset="0.5"/>
                                <GradientStop Color="Transparent" Offset="1"/>
                            </LinearGradientBrush>
                        </Grid.Resources>
    
                        <Canvas x:Name="Canvas" 
                                ClipToBounds="True" 
                                DockPanel.Dock="Top"  
                                Height="{Binding ElementName=Content, Path=ActualHeight}">
    
                            <Border 
                                BorderBrush="{TemplateBinding BorderBrush}"
                                Canvas.Right="0"
                                Canvas.ZIndex="0"
                                BorderThickness="{TemplateBinding BorderThickness}"
                                Background="{TemplateBinding Background}"
                                Padding="{TemplateBinding Padding}"
                                MinWidth="{Binding ElementName=Canvas, Path=ActualWidth}"
                                SnapsToDevicePixels="true"
                                x:Name="Content"
                            >
                                <ContentPresenter
                                    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
                                    Content="{Binding RelativeSource={RelativeSource AncestorType=Label}, Path=Content}"
                                    RecognizesAccessKey="True"
                                    SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
                                    VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
                                >
                                    <ContentPresenter.Resources>
                                        <Style TargetType="TextBlock">
                                            <Setter Property="FontSize" Value="{Binding FontSize, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                            <Setter Property="FontWeight" Value="{Binding FontWeight, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                            <Setter Property="FontStyle" Value="{Binding FontStyle, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                            <Setter Property="FontFamily" Value="{Binding FontFamily, RelativeSource={RelativeSource AncestorType={x:Type Label}}}"/> 
                                        </Style>
                                    </ContentPresenter.Resources>
    
                                </ContentPresenter>
                            </Border>
                            <Label 
                                x:Name="Ellipses" 
                                Canvas.Left="0" 
                                Canvas.ZIndex="10"
                                FontWeight="{TemplateBinding FontWeight}"
                                FontSize="{TemplateBinding FontSize}"
                                FontFamily="{TemplateBinding FontFamily}"
                                FontStyle="{TemplateBinding FontStyle}"
                                VerticalContentAlignment="Center" 
                                OpacityMask="{StaticResource HeaderBackgroundOpacityMask}" 
                                Background="{TemplateBinding Background}"
                                Foreground="RoyalBlue"
                                Height="{Binding ElementName=Content, Path=ActualHeight}" 
                                Content="...&#160;&#160;&#160;">
                                <Label.Resources>
                                    <Style TargetType="Label">
                                        <Style.Triggers>
                                            <DataTrigger Value="true">
                                                <DataTrigger.Binding>
                                                    <MultiBinding Converter="{StaticResource GteConverter}">
                                                        <Binding ElementName="Canvas" Path="ActualWidth"/>
                                                        <Binding ElementName="Content" Path="ActualWidth"/>
                                                    </MultiBinding>
                                                </DataTrigger.Binding>
                                                <Setter Property="Visibility" Value="Hidden"/>
                                            </DataTrigger>
                                        </Style.Triggers>
                                    </Style>
                                </Label.Resources>
    
                            </Label>
                        </Canvas>
    
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsEnabled"
                                 Value="false">
                            <Setter Property="Foreground"
                                    Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    
    <c:GteConverter x:Key="GteConverter"/>
    
    public class RelationalValueConverter : IMultiValueConverter
    {
        public enum RelationsEnum
        {
            Gt,Lt,Gte,Lte,Eq,Neq
        }
    
        public RelationsEnum Relations { get; protected set; }
    
        public RelationalValueConverter(RelationsEnum relations)
        {
            Relations = relations;
        }
    
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            if(values.Length!=2)
                throw new ArgumentException(@"Must have two parameters", "values");
    
            var v0 = values[0] as IComparable;
            var v1 = values[1] as IComparable;
    
            if(v0==null || v1==null)
                throw new ArgumentException(@"Must arguments must be IComparible", "values");
    
            var r = v0.CompareTo(v1);
    
            switch (Relations)
            {
                case RelationsEnum.Gt:
                    return r > 0;
                    break;
                case RelationsEnum.Lt:
                    return r < 0;
                    break;
                case RelationsEnum.Gte:
                    return r >= 0;
                    break;
                case RelationsEnum.Lte:
                    return r <= 0;
                    break;
                case RelationsEnum.Eq:
                    return r == 0;
                    break;
                case RelationsEnum.Neq:
                    return r != 0;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    public class GtConverter : RelationalValueConverter
    {
        public GtConverter() : base(RelationsEnum.Gt) { }
    }
    public class GteConverter : RelationalValueConverter
    {
        public GteConverter() : base(RelationsEnum.Gte) { }
    }
    public class LtConverter : RelationalValueConverter
    {
        public LtConverter() : base(RelationsEnum.Lt) { }
    }
    public class LteConverter : RelationalValueConverter
    {
        public LteConverter() : base(RelationsEnum.Lte) { }
    }
    public class EqConverter : RelationalValueConverter
    {
        public EqConverter() : base(RelationsEnum.Eq) { }
    }
    public class NeqConverter : RelationalValueConverter
    {
        public NeqConverter() : base(RelationsEnum.Neq) { }
    }