C# 如何截断引号中的文本字符串并保留引号?

C# 如何截断引号中的文本字符串并保留引号?,c#,wpf,text,C#,Wpf,Text,我用引号显示标题的空间有限: “这是一个简短的标题” 因此,如果标题太长,则需要将其截断,并用省略号指示缺少的字符: “这太长了,trun也是……” 我最初有一个转换器,它计算字符数并返回一个带引号的字符串,但由于使用比例字体,结果不一致。到目前为止,我想到的最好的方法是: <TextBlock Grid.Column="3" Margin="5" Text="{Binding Title, Mo

我用引号显示标题的空间有限:

“这是一个简短的标题”

因此,如果标题太长,则需要将其截断,并用省略号指示缺少的字符:

“这太长了,trun也是……”

我最初有一个转换器,它计算字符数并返回一个带引号的字符串,但由于使用比例字体,结果不一致。到目前为止,我想到的最好的方法是:

<TextBlock Grid.Column="3"
           Margin="5"
           Text="{Binding Title, Mode=OneWay, StringFormat='{}\'{0}\''}"
           TextTrimming="CharacterEllipsis">
这在某些时候起了作用。根据标题的不同,如果截短的文本短了一点,我有时会得到结尾。但是,我不能使用它,因为如果标题足够短,不需要截断,我会得到:

“这是短的”

在标题和结尾之间留有空格'

我已经研究过将列宽传递给转换器的可能性,但还没有找到一种方法——除非我一直在使用错误的术语进行搜索


有什么方法可以达到我想要的效果吗?

如果你真的需要找到适合给定可用空间的最大文本(考虑FontSize/Family/etc),你可以通过创建一个临时的新文本框来计算,并调整/测量它,直到指定的文本足够短:

  • 创建一个新的文本框并将文本分配给它

    =>您希望在测试文本中包含前导和尾随“'”和“…”

  • 测量新文本框的大小,了解相对于FontFamily/FontSize/等,显示文本需要多少空间

    =>要测量控件的大小,请参阅:

  • 但是,另一种方法是让控件计算它想要的大小。为此,您需要调用Measure,并将其传递给建议的大小。在本例中,您希望传递一个无限大的控件(这意味着控件可以任意大),因为这是Canvas在布局传递中要做的:

    lb.Measure(新尺寸(双正不确定度,双正不确定度)); Debug.WriteLine(lb.DesiredSize.Width)

    对Measure的调用实际上不会更改控件的宽度、渲染或实际宽度。它只是告诉标签计算它想要的大小,并将该值放入其DesiredSize(该属性的唯一目的是保存上次度量调用的结果)

  • 如果大于可用空间(如columnSize),则删除1个字符并再次测量

    =>要将列宽和文本传递到转换器中,可以使用多重绑定:一个绑定用于文本,另一个绑定用于列定义

  • xaml


    您可以在视图(=转换器)中完成所有这些操作,但可能最好将其放在VM中。由于ColumnDefinition的宽度是一个DependencyProperty,您可以将其绑定到VM上的一个属性,并在将最终(拟合)文本指定给绑定到TextBox.text的属性之前进行测量。

    这似乎对我有效:

    <Grid HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
    
        <TextBlock Text="'"/>
        <TextBlock Grid.Column="1" Text="Some long dynamic text that could be truncated" TextTrimming="CharacterEllipsis"/>
        <TextBlock Grid.Column="2" Text="'"/>
    </Grid>
    
    对于
    DockPanel
    您只需记住:

    如果将
    LastChildFill
    属性设置为
    true
    ,这是默认设置,
    DockPanel
    的最后一个子元素始终填充剩余空间,而不考虑在最后一个子元素上设置的任何其他停靠值


    作为替代方案,您可以使用以下方法:

    <TextBlock>'<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding AlbumName, Mode=OneWay}"/>'</TextBlock>  
    
    “”
    
    我对此进行了测试,如果文本块太长,似乎只有内部文本块有省略号。

    我对此(TextBlock中的TextBlock)不是特别满意,但它似乎很有效。

    我想在某些情况下,这可能会在文本和结尾之间产生一个空格,但它可能太小而不明显。@ChrisF只要
    水平对齐
    设置为
    右侧
    中间
    ,我认为不会有任何明显的空间。但是如果你发现一个场景中确实出现了空格,一定要让我知道。
    public class MyConverter : IMultiValueConverter
    {
        public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
        {
            var text = (string)values[0];
            var colDefinition = (ColumnDefinition)values[1];
                
            /// 
            /// implement your code
            /// 
            var colWidth = colDefinition.Width;
    
            return text;
        }
    
        public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
    
    <Grid HorizontalAlignment="Left">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition/>
            <ColumnDefinition Width="Auto"/>
        </Grid.ColumnDefinitions>
    
        <TextBlock Text="'"/>
        <TextBlock Grid.Column="1" Text="Some long dynamic text that could be truncated" TextTrimming="CharacterEllipsis"/>
        <TextBlock Grid.Column="2" Text="'"/>
    </Grid>
    
    <DockPanel HorizontalAlignment="Left">
        <TextBlock DockPanel.Dock="Left" Text="'"/>
        <TextBlock DockPanel.Dock="Right" Text="'"/>
        <TextBlock Grid.Column="1" Text="Some long dynamic text that could be truncated" TextTrimming="CharacterEllipsis"/>
    </DockPanel>
    
    <TextBlock>'<TextBlock TextTrimming="CharacterEllipsis" Text="{Binding AlbumName, Mode=OneWay}"/>'</TextBlock>