【问题标题】:Silverlight TextBlock: Convert Text to InlineCollectionSilverlight TextBlock:将文本转换为 InlineCollection
【发布时间】:2011-06-11 16:07:00
【问题描述】:

考虑以下标记声明:

<TextBlock>
 <Run>abcdefghijklmnopqrstuvwxyz</Run>
 <LineBreak/>
 <Run>0123456789</Run>
</TextBlock>

我想将任何数据绑定到 TextBlock 并将这些数据转换为 InlineCollection。用数据绑定来做这件事会非常优雅。另一种方法是观察我的数据源并使用代码隐藏中 TextBlock 类中的 Inlines-Property。

我尝试了以下方法,但没有成功:

<TextBlock>
 <Binding Path="MyDataSource" Converter="{StaticResource MyTextConverter}"/>
</TextBlock>

我想要做的是通过将我的 TextBlock 封装在 ViewBox 中来实现自动字体缩放,同时在任意字母计数后生成 LineBreaks。

提前感谢您的帮助。 最好的问候。

【问题讨论】:

    标签: silverlight binding textblock


    【解决方案1】:

    这太容易了……"\r\n" 在正确的位置上完成了这项工作。

    【讨论】:

      【解决方案2】:

      我猜你只需要将转换器分配给 TextBlock 的 TextProperty。 然后您的转换器添加\r\n 以在需要时获得换行符。

      【讨论】:

        【解决方案3】:

        我想我通过对 TextBlock 进行子类化以使 InlineCollection 可绑定并在 xaml 标记字符串和 InlineCollection(或内联的通用列表)之间编写转换器来回答这个问题]

        Details here on the Stack

        正如 infografnet 所指出的,TextBlock 类的 Silverlight 版本是 sealed,这使得我的 WPF 子类建议无效。

        【讨论】:

        • 在 Silverlight 中 TextBlock 类是密封的/不可继承的,所以这个解决方案不是解决方案
        • @infografnet,所以,在 Silverlight 中,TextBlock 不是 msdn.microsoft.com/en-us/library/…
        • 您提供的链接涉及 .Net 4.5 和 Silverlight 在这里:TextBlock Class
        • @infografnet,我已经相应地取消了我的答案,但是,不只是删除,因为我认为差异与问题有关。
        【解决方案4】:

        我使用this 回答了一个与 WPF 相关的问题,以提出一种 Silverlight 行为,它可以在 Silverlight 中为 TextBlock 添加简单的格式。格式化是通过 Xml 元素完成的,这些元素的工作方式类似于在元素本身内格式化 TextBlock 的方式。可以使用粗体、斜体、下划线和换行符元素。

        首先,行为定义如下:

        public static class FormattedTextBlockBehavior { public static string GetFormattedText(DependencyObject obj) { return (string) obj.GetValue(FormattedTextProperty); } public static void SetFormattedText(DependencyObject obj, string value) { obj.SetValue(FormattedTextProperty, value); } public static readonly DependencyProperty FormattedTextProperty = DependencyProperty.RegisterAttached("FormattedText", typeof (string), typeof (FormattedTextBlockBehavior), new PropertyMetadata("", FormattedTextChanged)); private static Inline Traverse(string value) { // Get the sections/inlines string[] sections = SplitIntoSections(value); // Check for grouping if (sections.Length.Equals(1)) { string section = sections[0]; string token; // E.g <Bold> int tokenStart, tokenEnd; // Where the token/section starts and ends. // Check for token if (GetTokenInfo(section, out token, out tokenStart, out tokenEnd)) { // Get the content to further examination string content = token.Length.Equals(tokenEnd - tokenStart) ? null : section.Substring(token.Length, section.Length - 1 - token.Length*2); switch (token) { case "<Bold>": var b = new Bold(); b.Inlines.Add(Traverse(content)); return b; case "<Italic>": var i = new Italic(); i.Inlines.Add(Traverse(content)); return i; case "<Underline>": var u = new Underline(); u.Inlines.Add(Traverse(content)); return u; case "<LineBreak/>": return new LineBreak(); case "<LineBreak />": return new LineBreak(); default: return new Run { Text = section }; } } return new Run { Text = section }; } var span = new Span(); foreach (string section in sections) span.Inlines.Add(Traverse(section)); return span; } /// <summary> /// Examines the passed string and find the first token, where it begins and where it ends. /// </summary> /// <param name="value">The string to examine.</param> /// <param name="token">The found token.</param> /// <param name="startIndex">Where the token begins.</param> /// <param name="endIndex">Where the end-token ends.</param> /// <returns>True if a token was found.</returns> private static bool GetTokenInfo(string value, out string token, out int startIndex, out int endIndex) { token = null; endIndex = -1; startIndex = value.IndexOf("<"); int startTokenEndIndex = value.IndexOf(">"); // No token here if (startIndex < 0) return false; // No token here if (startTokenEndIndex < 0) return false; token = value.Substring(startIndex, startTokenEndIndex - startIndex + 1); // Check for closed token. E.g. <LineBreak/> if (token.EndsWith("/>")) { endIndex = startIndex + token.Length; return true; } string endToken = token.Insert(1, "/"); // Detect nesting; int nesting = 0; int pos = 0; do { int tempStartTokenIndex = value.IndexOf(token, pos); int tempEndTokenIndex = value.IndexOf(endToken, pos); if (tempStartTokenIndex >= 0 && tempStartTokenIndex < tempEndTokenIndex) { nesting++; pos = tempStartTokenIndex + token.Length; } else if (tempEndTokenIndex >= 0 && nesting > 0) { nesting--; pos = tempEndTokenIndex + endToken.Length; } else // Invalid tokenized string return false; } while (nesting > 0); endIndex = pos; return true; } /// <summary> /// Splits the string into sections of tokens and regular text. /// </summary> /// <param name="value">The string to split.</param> /// <returns>An array with the sections.</returns> private static string[] SplitIntoSections(string value) { var sections = new List<string>(); while (!string.IsNullOrEmpty(value)) { string token; int tokenStartIndex, tokenEndIndex; // Check if this is a token section if (GetTokenInfo(value, out token, out tokenStartIndex, out tokenEndIndex)) { // Add pretext if the token isn't from the start if (tokenStartIndex > 0) sections.Add(value.Substring(0, tokenStartIndex)); sections.Add(value.Substring(tokenStartIndex, tokenEndIndex - tokenStartIndex)); value = value.Substring(tokenEndIndex); // Trim away } else { // No tokens, just add the text sections.Add(value); value = null; } } return sections.ToArray(); } private static void FormattedTextChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) { var value = e.NewValue as string; var textBlock = sender as TextBlock; if (textBlock != null) textBlock.Inlines.Add(Traverse(value)); }

        那么,从xaml本身来看,行为可以参考如下:

          xmlns:Helpers="clr-namespace:Namespace.Helpers" 
        
          <TextBlock Grid.Row="0" Margin="10,10,10,10" TextWrapping="Wrap" FontSize="14" Helpers:FormattedTextBlockBehavior.FormattedText="{Binding ViewModel.Text}" />
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-07-01
          • 2012-10-27
          • 1970-01-01
          • 2010-12-12
          相关资源
          最近更新 更多