【问题标题】:How to inject a formatted paragraph into a TextBlock?如何将格式化的段落注入 TextBlock?
【发布时间】:2015-08-13 08:50:27
【问题描述】:

我正在尝试将段落的格式化内容传输到 TextBlock,但格式消失了:

// Create a formatted paragraph
Paragraph para = new Paragraph();
para.FontSize = 25;
para.FontWeight = FontWeights.Bold;
para.Inlines.Add(new Run("Text of paragraph."));

// Create a span with the content of the paragraph (FontSize 25 and FontWeight Bold stay alive)
Span span = new Span(para.ContentStart, para.ContentEnd);

// Create a TextBlock with the span (FontSize 25 and FontWeight Bold get lost)
TextBlock textBlock = new TextBlock();
textBlock.Inlines.Add(span);

可以做些什么来保持格式?提前致谢。

更新
段落的格式在运行时是已知的,所以我不能手动一一应用属性值。

更新 2
问题的背景是我想测量格式化段落的长度,如果它们被拉伸到一行。 这可以通过 TextBlock 来完成。段落位于 TableCells 中,我想自动调整列宽。

【问题讨论】:

    标签: c# wpf formatting textblock paragraph


    【解决方案1】:

    TextBlock不能应用格式化,它类似于Label,如果需要格式化可以使用<RichTextBox/>代替。您可以将其设为ReadOnly 以避免编辑。

    例子:

       <RichTextBox Margin="10" ReadOnly="true">
            <FlowDocument>
                <Paragraph FontSize="36">Hello, world!</Paragraph>
                <Paragraph FontStyle="Italic" TextAlignment="Left" FontSize="14" Foreground="Gray">Thanks to the RichTextBox control, this FlowDocument is completely editable!</Paragraph>
            </FlowDocument>
        </RichTextBox>
    

    【讨论】:

    • 我必须使用IsReadOnly
    【解决方案2】:

    与@un-lucky 所说的相反,TextBlock 确实具有这种格式化功能。

    查看this article

    通过将样式直接应用到跨度,您可以将其保留在文本框中。

    摘录:

                         TextBlock tb = new TextBlock();
                        tb.TextWrapping = TextWrapping.Wrap;
                        tb.Margin = new Thickness(10);
                        tb.Inlines.Add("An example on ");
                        tb.Inlines.Add(new Run("the TextBlock control ") { FontWeight = FontWeights.Bold });
                        tb.Inlines.Add("using ");
                        tb.Inlines.Add(new Run("inline ") { FontStyle = FontStyles.Italic });
                        tb.Inlines.Add(new Run("text formatting ") { Foreground = Brushes.Blue });
                        tb.Inlines.Add("from ");
                        tb.Inlines.Add(new Run("Code-Behind") { TextDecorations = TextDecorations.Underline });
                        tb.Inlines.Add(".");
    

    更新 得到您的更新,但您可以从段落中获取字体和样式,然后直接应用它们。至少从您上面的示例看来是这样。

    TextBlock tb = new TextBlock();
    
    Paragraph para = new Paragraph();
    para.FontSize = 25;
    para.FontWeight = FontWeights.Bold;
    para.Inlines.Add(new Run("new paragraph"));
    
    Span span = new Span(para.ContentStart, para.ContentEnd);
    span.FontWeight = para.FontWeight;
    span.FontSize = para.FontSize;
    
    tb.Inlines.Add(span);
    

    这对你有用吗?

    【讨论】:

    • 我不能直接应用样式,请看我上面的更新。
    • 查看我上面的更新 - 您可以从段落中获取样式,并且仍然可以直接在代码中应用它们。
    • 段落的格式可以是任何东西,不能总是指整个跨度,所以很遗憾,我不能这样做。请参阅我的更新 2。
    【解决方案3】:

    您可以使用 RichTextBox 来代替 TextBlock 并实现必要的格式化 这是一个示例代码

    // Create a formatted paragraph
            Paragraph para = new Paragraph();
            para.FontSize = 25;
            para.FontWeight = FontWeights.Bold;
            para.Inlines.Add(new Run("Text of paragraph."));
    
            Myrichtextboxtbx.Document.Blocks.Add(para);
    

    然后将你的richtextbox添加到xaml

    【讨论】:

    • 请参阅上面的更新 2。
    【解决方案4】:

    我达到了以下解决方案:

    // Create a formatted Paragraph
    Paragraph para = new Paragraph();
    para.FontSize = 25;
    para.FontWeight = FontWeights.Bold;
    para.Inlines.Add(new Run("Text of paragraph."));
    
    // Clone all Inlines
    List<Inline> clonedInlines = new List<Inline>();
    foreach (Inline inline in para.Inlines)
    {
        Inline clonedInline = ElementClone<Inline>(inline);
        clonedInlines.Add(clonedInline);
    }
    
    // Get all Paragraph properties with a set value
    List<DependencyProperty> depProps = DepPropsGet(para, PropertyFilterOptions.SetValues);
    
    // Apply the Paragraph values to each Inline
    foreach (DependencyProperty depProp in depProps)
    {
        object propValue = para.GetValue(depProp);
    
        foreach (Inline clonedInline in clonedInlines)
        {
            // Can the Inline have the value?
            if (depProp.OwnerType.IsAssignableFrom(typeof(Inline)))
            {
                // Apply the Paragraph value
                clonedInline.SetValue(depProp, propValue);
            }
        }
    }
    
    // Create a TextBlock with the same properties as the Paragraph
    TextBlock textBlock = new TextBlock();
    textBlock.Inlines.AddRange(clonedInlines);
    
    /// <summary>
    /// Cloner.
    /// </summary>
    public static T ElementClone<T>(T element)
    {
        // Element to Stream
        MemoryStream memStream = new MemoryStream();
        XamlWriter.Save(element, memStream);
    
        // Cloned element from Stream
        object clonedElement = null;
        if (memStream.CanRead)
        {
            memStream.Seek(0, SeekOrigin.Begin);
            clonedElement = XamlReader.Load(memStream);
            memStream.Close();
        }
        return (T)clonedElement;
    }
    
    /// <summary>
    /// Property-Getter.
    /// </summary>
    public static List<DependencyProperty> DepPropsGet(DependencyObject depObj, PropertyFilterOptions filter)
    {
        List<DependencyProperty> result = new List<DependencyProperty>();
    
        foreach (PropertyDescriptor pd in TypeDescriptor.GetProperties(depObj, new Attribute[] { new PropertyFilterAttribute(filter) }))
        {
            DependencyPropertyDescriptor dpd = DependencyPropertyDescriptor.FromProperty(pd);
    
            if (dpd != null)
            {
                result.Add(dpd.DependencyProperty);
            }
        }
    
        return result;
    }
    

    【讨论】:

      猜你喜欢
      • 2010-10-03
      • 1970-01-01
      • 1970-01-01
      • 2019-09-27
      • 1970-01-01
      • 2021-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多