在XAML中动态格式化ListBox中的文本项。

问题描述 投票:0回答:1

我正在使用Caliburn Micro,并且有一个ListBox,它可以显示我从ViewModel中绑定到它的项目列表。

然而,我现在正在研究如何动态格式化每个ListItem,即在我的例子中,每个字符串可以有N个值,这些值在两个标记之间,我需要将这些值格式化为粗体。

我能够将文本解析成一个列表,然后标记哪些单词或单词块需要格式化,哪些不需要,但是我不确定如何在我的ListBox中显示这些。我看了一下,有些人推荐使用一个转换器来解析文本字符串?

目前我的listbox的XAML看起来像--当我只需要格式化一个关键字的时候,这是可行的,但是后来我发现一个字符串中可能会出现多个关键字,所以无法再预测结构。

<ListBox ItemsSource="{Binding HighlightList}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <Run Text="{Binding Path=mStartText}"/>
                <Run Text="{Binding Path=mBoldText}"/>
                <Run Text="{Binding Path=mEndText}"/>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

有没有人能够实现类似的事情?先谢谢大家的提示!

EDIT:

那么,为了进一步明确,让我们假设我有两个字符串。

字符串1 - "这是一个 测试 弦"

字符串2 - "这个 也是 测试 绳子

我要做的是在ListBox中显示上述字符串,用EM标签(上面例子中的Italics)包裹的字符串要加粗,字体颜色为红色。

我现在所做的是创建一个列表对象,每个对象将有两个变量--字符串内容,以及字符串类型(高亮或不高亮),并对每个字符串进行解析和分解,这样我就可以标记出哪些部分可以原样打印,哪些需要以高亮格式打印。

ViewModel。

    public ObservableCollection<HighlightItem> HighlightList
    {
        get
        {
            return _highlightList;
        }
        set
        {
            _highlightList = value;
            NotifyOfPropertyChange(() => HighlightList);
        }
    }

public void ParseHighlights()
        {
            ObservableCollection<HighlightItem> hlList = new ObservableCollection<HighlightItem>();

            string START_HL_TOKEN = "<em>";
            string END_HL_TOKEN = "</em>";

            if (_documentSnippets.Count > 0)
            {
                foreach (var hlItem in _documentSnippets.Snippets["text"])
                {
                    // Remove tab characters
                    string temp = hlItem.Replace("\t", "");

                    // Remove multiple newline characters and replace with a single one
                    Regex regex = new Regex("(\\n){2,}");

                    string clean_temp = regex.Replace(temp, "\n");
                    string startText = "", hlText = "", endText = "";
                    int start_idx = 0;
                    int end_idx = 0;
                    List<string> stringTokenized = new List<string>();

// THIS BELOW IS PART OF MY NEW APPROACH
                    while(start_idx != clean_temp.Length)
                    {
                        end_idx = clean_temp.IndexOf(START_HL_TOKEN, start_idx);

                        // Highlight token is at the start
                        if(end_idx == 0)
                        {
                            start_idx = end_idx;
                            end_idx = clean_temp.IndexOf(END_HL_TOKEN, start_idx);
                            stringTokenized.Add(clean_temp.Substring(start_idx + 4, end_idx - start_idx));

                            // Move pointer to start of next section, keeping in mind the length of the END token
                            start_idx = end_idx + 4;
                        }
                        else if(end_idx == -1)
                        {
                            end_idx = clean_temp.Length;
                            stringTokenized.Add(clean_temp.Substring(start_idx, end_idx - start_idx));
                            start_idx = end_idx;
                        }
                        else
                        {
                            stringTokenized.Add(clean_temp.Substring(start_idx, end_idx - start_idx));

                            start_idx = end_idx;
                            end_idx = clean_temp.IndexOf(END_HL_TOKEN, start_idx);
                            stringTokenized.Add(clean_temp.Substring(start_idx + 4, end_idx - start_idx));

                            // Move pointer to start of next section
                            start_idx = end_idx + 4;
                        }
                    }
// END OF MY NEW APPROACH

                    // Token is at the beginning of the snippet
                    if (hlItem.IndexOf(START_HL_TOKEN) == 0)
                    {
                        hlText = clean_temp.Substring(clean_temp.IndexOf(START_HL_TOKEN) + START_HL_TOKEN.Length,
                                                   clean_temp.IndexOf(END_HL_TOKEN) - START_HL_TOKEN.Length);

                        endText = clean_temp.Substring(clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length,
                                                   clean_temp.Length - (clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length));
                    }
                    // Token is at the end of the snippet
                    else if (clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length == clean_temp.Length)
                    {
                        startText = clean_temp.Substring(0,
                                                     clean_temp.Length - clean_temp.IndexOf(START_HL_TOKEN));
                        hlText = clean_temp.Substring(clean_temp.IndexOf(START_HL_TOKEN),
                                                  clean_temp.Length - clean_temp.IndexOf(START_HL_TOKEN));
                    }
                    // Token is in the middle of the snippet
                    else
                    {
                        startText = clean_temp.Substring(0,
                                                     clean_temp.IndexOf(START_HL_TOKEN));

                        hlText = clean_temp.Substring(clean_temp.IndexOf(START_HL_TOKEN) + START_HL_TOKEN.Length,
                                                  clean_temp.IndexOf(END_HL_TOKEN) - clean_temp.IndexOf(START_HL_TOKEN) - (END_HL_TOKEN.Length - 1));

                        endText = clean_temp.Substring(clean_temp.IndexOf(END_HL_TOKEN) + END_HL_TOKEN.Length,
                                                   clean_temp.Length - clean_temp.IndexOf(END_HL_TOKEN) - END_HL_TOKEN.Length);
                    }

                    HighlightItem snippet = new HighlightItem(startText, hlText, endText);
                    hlList.Add(snippet);
                }

                HighlightList = hlList;
            }

        }

所以在上面的模型中,我采用了我的老方法,我假设字符串中只有一个标签,但当我意识到有时会有多个标签时,我开始采用新的方法,建立一个字符串的列表表示,标记哪些部分需要正常打印,哪些需要高亮打印。

另外对我的命名标准,一个多月前才开始使用WPF和C#,所以还不太了解所有的命名习惯,抱歉!

c# wpf xaml caliburn.micro
1个回答
0
投票

按照Sinatr的提示,我找到了下面的文章,使用一个自定义的附加属性对我来说是个好办法。WPF TextBlock格式化粗体来自字符串属性

随后,我能够提供嵌入标记的字符串,它们将被适当地打印出来! 谢谢你的帮助

© www.soinside.com 2019 - 2024. All rights reserved.