Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/silverlight/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Silverlight文本块:将文本转换为InlineCollection_Silverlight_Binding_Textblock - Fatal编程技术网

Silverlight文本块:将文本转换为InlineCollection

Silverlight文本块:将文本转换为InlineCollection,silverlight,binding,textblock,Silverlight,Binding,Textblock,考虑以下标记声明: <TextBlock> <Run>abcdefghijklmnopqrstuvwxyz</Run> <LineBreak/> <Run>0123456789</Run> </TextBlock> abcdefghijklmnopqrstuvwxyz 0123456789 我想将任何数据绑定到TextBlock,并将此数据转换为InlineCollection。使用数据绑定来实现这一

考虑以下标记声明:

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

abcdefghijklmnopqrstuvwxyz
0123456789
我想将任何数据绑定到TextBlock,并将此数据转换为InlineCollection。使用数据绑定来实现这一点是非常优雅的。另一种方法是观察我的数据源,并在代码隐藏中使用TextBlock类的Inlines属性

我尝试了以下方法,但无效:

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

我想做的是通过将文本块封装在ViewBox中实现自动字体缩放,同时在任意字母计数后生成换行符

提前感谢您的帮助。
致以最诚挚的问候。

这太容易成为事实了<代码>“\r\n”在正确的位置执行此任务。

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

我想我通过对文本块进行子分类以使InlineCollection可绑定,并在xaml标记字符串和InlineCollection(或通用Inlines列表)之间编写一个转换器来解决这个问题

正如infografnet所指出的,
TextBlock
类的版本是
密封的
,这使得我的分类建议无效。

我使用WPF相关问题的答案来提出Silverlight行为,它可以在Silverlight中为文件添加简单的格式。格式化是通过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));
    }
  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}" />

公共静态类FormattedTextBlockBehavior
{
公共静态字符串GetFormattedText(DependencyObject obj)
{
返回(字符串)obj.GetValue(FormattedTextProperty);
}
公共静态void SetFormattedText(DependencyObject对象,字符串值)
{
对象设置值(FormattedTextProperty,值);
}
公共静态只读DependencyProperty FormattedTextProperty=
DependencyProperty.RegisterAttached(“FormattedText”,
类型(字符串),
typeof(FormattedTextBlockBehavior),
新属性元数据(“,FormattedTextChanged”);
私有静态内联遍历(字符串值)
{
//获取节/内联线
字符串[]节=拆分为节(值);
//检查分组
if(截面长度等于(1))
{
字符串段=段[0];
字符串标记;//例如
int tokenStart,tokenEnd;//标记/节开始和结束的位置。
//检查代币
if(GetTokenInfo(节,out-token,out-tokenStart,out-tokenEnd))
{
//获取内容以供进一步检查
string content=token.Length.Equals(tokenEnd-tokenStart)
无效的
:section.Substring(token.Length,section.Length-1-token.Length*2);
交换机(令牌)
{
案例“”:
var b=新的粗体();
b、 添加(遍历(内容));
返回b;
案例“”:
var i=新斜体();
i、 添加(遍历(内容));
返回i;
案例“”:
var u=新下划线();
u、 添加(遍历(内容));
返回u;
案例“”:
返回新的换行符();
案例“”:
返回新的换行符();
违约:
返回新运行
{
文本=节
};
}
}
返回新运行
{
文本=节
};
}
var span=新span();
foreach(段中的字符串段)
span.Inlines.Add(导线测量(剖面));
返回跨度;
}
/// 
///检查传递的字符串并找到第一个标记,它从哪里开始,从哪里结束。
/// 
///要检查的字符串。
///找到了令牌。
///令牌的起始位置。
///结束标记结束的位置。
///如果找到令牌,则为True。
私有静态bool GetTokenInfo(字符串值、out字符串标记、out int startIndex、out int endIndex)
{
令牌=null;
endIndex=-1;
startIndex=value.IndexOf(“”);
//这里没有代币
如果(起始索引<0)
返回false;
//这里没有代币
如果(起始肯内德指数<0)
返回false;
token=value.Substring(startIndex,startTokenEndIndex-startIndex+1);
//检查已关闭的令牌。例如。
if(令牌.EndsWith(“/>”)
{
endIndex=startIndex+token.Length;
返回true;
}
字符串endToken=token.Insert(1,“/”);
//检测嵌套;
int嵌套=0;
int pos=0;
做
{
int tempStartTokenIndex=value.IndexOf(令牌,位置);
int tempEndTokenIndex=value.IndexOf(endToken,pos);
如果(tempStartTokenIndex>=0&&tempStartTokenIndex=0&&nesting>0)
{
筑巢--;
pos=tempEndTokenIndex+endToken.Length;
}
else//无效的tokeniz