5

我想将文本块的部分文本设为粗体。这是我在 IValueConverter 中尝试过的,但它似乎不起作用。

public class Highlighter : IValueConverter
    {


        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (value == null)
            {
                return null;
            }

            return "Question1:<Bold>Answer1</Bold>, Question2:<Bold>Answer2</Bold>, Question3:<Bold>Answer3</Bold>";

        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }

这不会使答案变粗。

这就是我在 XAML 中使用它的方式。

<TextBlock Height="Auto" Width="Auto" MaxHeight="64" Text="{Binding Path=QuestionAnswer, Mode=OneWay, Converter={x:Static Highlighter}}" />

有没有办法通过格式化文本或将 TextBlock 发送到转换器来实现这一点?

4

2 回答 2

14

绝对有可能与TextBlock控制有关,但考虑到您可能想要切换到其他控制(ItemsControl例如)的所有努力。

无论如何,这是一个解决方案。实际上有几个问题需要解决:

  1. TextBlock.Text属性是string,并且您不能将预格式化的文本分配给它
  2. TextBlock.Inlines可以接受格式化文本,但它是只读属性
  3. 您必须自己格式化文本(可能有简单的方法来解析带有标签的文本并将格式化的输出生成为Inline对象的集合,但我不知道)

您可以创建一个附加属性来处理前两个问题:

public static class TextBlockEx
{
    public static Inline GetFormattedText(DependencyObject obj)
    {
        return (Inline)obj.GetValue(FormattedTextProperty);
    }

    public static void SetFormattedText(DependencyObject obj, Inline value)
    {
        obj.SetValue(FormattedTextProperty, value);
    }

    public static readonly DependencyProperty FormattedTextProperty =
        DependencyProperty.RegisterAttached(
            "FormattedText",
            typeof(Inline),
            typeof(TextBlockEx),
            new PropertyMetadata(null, OnFormattedTextChanged));

    private static void OnFormattedTextChanged(
        DependencyObject o,
        DependencyPropertyChangedEventArgs e)
    {
        var textBlock = o as TextBlock;
        if(textBlock == null) return;

        var inline = (Inline)e.NewValue;
        textBlock.Inlines.Clear();
        if(inline != null)
        {
            textBlock.Inlines.Add(inline);
        }
    }
}

XAML 会改变一点:

<TextBlock local:TextBlockEx.FormattedText="{Binding Path=QuestionAnswer,
                                                     Mode=OneWay,
                                                     Converter={x:Static Highlighter}}" />

请注意,您需要将命名空间映射到 XAMLTextBlockEx中声明的位置。xmlns:local="clr-namepace:<namespace_name>"

现在您需要在转换器中构造格式化文本而不是纯文本来解决最后一个问题:

public object Convert(object value, Type targetType, object parameter,
    CultureInfo culture)
{
    if(value == null)
    {
        return null;
    }

    var span = new Span();
    span.Inlines.Add(new Run("Question1: "));
    span.Inlines.Add(new Run("Answer1") { FontWeight = FontWeights.Bold });
    span.Inlines.Add(new Run(", "));

    span.Inlines.Add(new Run("Question2: "));
    span.Inlines.Add(new Run("Answer2") { FontWeight = FontWeights.Bold });
    span.Inlines.Add(new Run(", "));

    span.Inlines.Add(new Run("Question3: "));
    span.Inlines.Add(new Run("Answer3") { FontWeight = FontWeights.Bold });

    return span;
}
于 2012-12-27T18:32:02.490 回答
2

是的,这样的事情应该让你走上正轨;

<TextBlock>
   <Run Text="Question / Binding / Whatever..."/>
   <Run Text="Answer / Binding / Whatever..." FontWeight="Bold"/>
</TextBlock>
于 2012-12-27T17:45:57.480 回答