如何将格式化段落注入 TextBlock?
How to inject a formatted paragraph into a TextBlock?
我正在尝试将段落的格式化内容传输到 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中,我想自动调整列宽。
格式化不能应用到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>
与@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);
这对你有用吗?
您可以使用 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);
然后将您的富文本框添加到 xaml
我得到了以下解决方案:
// 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;
}
我正在尝试将段落的格式化内容传输到 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中,我想自动调整列宽。
格式化不能应用到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>
与@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);
这对你有用吗?
您可以使用 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);
然后将您的富文本框添加到 xaml
我得到了以下解决方案:
// 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;
}