使用iValueConverter格式化TextBlock文本的一部分

时间:2012-12-27 17:40:57

标签: wpf ivalueconverter

我想将文本块的一部分粗体化。这是我在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发送到转换器来实现这一目标?

2 个答案:

答案 0 :(得分:13)

绝对可以使用TextBlock控件,但考虑到您可能想要切换到其他控件的所有工作(例如ItemsControl)。

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

  1. TextBlock.Text属性为string,您无法为其指定预先格式化的文字
  2. TextBlock.Inlines可以接受格式化文本,但它是只读属性
  3. 你必须自己格式化文本(可能有简单的方法用标签解析文本并生成格式化的输出作为Inline个对象的集合,但我不知道任何事情)
  4. 您可以创建附加属性来处理前两个问题:

    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}}" />
    

    请注意,您需要映射在XAML中TextBlockEx中声明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;
    }
    

答案 1 :(得分:2)

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

<TextBlock>
   <Run Text="Question / Binding / Whatever..."/>
   <Run Text="Answer / Binding / Whatever..." FontWeight="Bold"/>
</TextBlock>
相关问题