RichTextBox WPF 限制一行内容

RichTextBox WPF limit content in one line

我需要将部分字符串加粗。由于 TextBlock 不支持将部分文本设为粗体,因此我转而使用 RichTextBox。现在,我希望我的 RichTextBox 限制为单行,如果内容较长以适合单行,它应该使用字符省略号来截断字符串。以下是我的 ViewModel 绑定到 RichTextBox,

    public class SearchSuggestionViewModel : BindableBase, IComparable<SearchSuggestionViewModel>
    {
    private Suggestion _suggestion;
    private string m_DocumentXaml = string.Empty;


    public SearchSuggestionViewModel(Suggestion suggestion)
        {
        _suggestion = suggestion;
        if (string.IsNullOrEmpty(suggestion.Text))
            return;
        string searchText = _suggestion.Text;
        FlowDocument document = new FlowDocument();
        Paragraph paragraph = new Paragraph();
        Run run = new Run();

        while (searchText.Contains("<b>"))
            {
            string initialText = searchText.Substring(0, searchText.IndexOf("<b>"));
            run.Text = initialText;
            paragraph.Inlines.Add(run);
            searchText = searchText.Substring(searchText.IndexOf("<b>") + "<b>".Length);
            string boldText = searchText;
            if (searchText.Contains("</b>"))
                boldText = searchText.Substring(0, searchText.IndexOf("</b>"));
            run = new Run();
            run.FontWeight = FontWeights.Bold;
            run.Text = boldText;
            paragraph.Inlines.Add(run);

            searchText = searchText.Substring(searchText.IndexOf("</b>") + "</b>".Length);
            }
        run = new Run();
        run.Text = searchText;
        paragraph.Inlines.Add(run);
        document.Blocks.Add(paragraph);
        DocumentXaml = XamlWriter.Save(document);
        }

    public string Id
        {
        get
            {
            return _suggestion.Id;
            }
        }


    public string SearchSuggestionText
        {
        get
            {
            if (!string.IsNullOrWhiteSpace( _suggestion.Text))
                return _suggestion.Text.Replace("<b>", "").Replace("</b>", "");
            return string.Empty;
            }
        }



    /// <summary>
    /// The text from the FsRichTextBox, as a XAML markup string.
    /// </summary>
    public string DocumentXaml
        {
        get
            {
            return m_DocumentXaml;
            }

        set
            {
            SetProperty(ref m_DocumentXaml, value, nameof(DocumentXaml));
            }
        }


    public override int GetHashCode()
        {
        return base.GetHashCode();
        }

    public override bool Equals(object obj)
        {
        if (!(obj is SearchSuggestionViewModel))
            return false;
        SearchSuggestionViewModel otherTag = (SearchSuggestionViewModel)obj;
        if (SearchSuggestionText.Equals(otherTag.SearchSuggestionText))
            return true;
        return false;
        }

    public int CompareTo(SearchSuggestionViewModel compareSearchSuggestionViewModel)
        {
        // A null value means that this object is greater.
        if (compareSearchSuggestionViewModel == null)
            return 1;

        else
            return this.SearchSuggestionText.CompareTo(compareSearchSuggestionViewModel.SearchSuggestionText);
        }
    public override string ToString()
        {
        return _suggestion.Text;
        }
    }

关于如何在行尾之前添加字符省略号的任何建议。

此致, 奥马尔

您应该可以使用 TextBlock 文本换行和文本修剪:

<TextBlock TextWrapping="WrapWithOverflow" TextTrimming="CharacterEllipsis">
    <Run>This text is</Run>
    <Run FontWeight="Bold" Text="partly bold"/>
    <Run>and wraps.</Run>
</TextBlock>

如果您以编程方式创建 TextBlock,它有一个 Inlines 属性,您可以向其中添加 Run 元素。

感谢mm8,他的回答给了我一个方向。但是我需要一个解决方案来绑定到 ViewModel 中的集合。字符串中粗体区域的数量是在运行时决定的。所以,我创建了一个依赖项 属性。以下为我工作。为将来的他人利益而分享。

TextBlockExtensions.cs

public class TextBlockExtensions
{
    public static IEnumerable<Inline> GetBindableInlines(DependencyObject obj)
    {
        return (IEnumerable<Inline>)obj.GetValue(BindableInlinesProperty);
    }

    public static void SetBindableInlines(DependencyObject obj, IEnumerable<Inline> value)
    {
        obj.SetValue(BindableInlinesProperty, value);
    }

    public static readonly DependencyProperty BindableInlinesProperty =
        DependencyProperty.RegisterAttached("BindableInlines", typeof(IEnumerable<Inline>), typeof(TextBlockExtensions), new PropertyMetadata(null, OnBindableInlinesChanged));

    private static void OnBindableInlinesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var Target = d as TextBlock;

        if (Target != null)
        {
            Target.Inlines.Clear();
            Target.Inlines.AddRange((System.Collections.IEnumerable)e.NewValue);
        }
    }
}

在我的 ViewModel 中,我添加了,

    private ObservableCollection<Inline> _searchSuggestionInlines;
    public ObservableCollection<Inline> SearchSuggestionInlines
    {
        get
        {
            return _searchSuggestionInlines;
        }
        set
        {
            SetProperty(ref _searchSuggestionInlines, value, nameof(SearchSuggestionInlines));
        }
    }

    //To populate the inlines
    public SearchSuggestionViewModel(Suggestion suggestion)
        {
        _suggestion = suggestion;
        if (string.IsNullOrEmpty(suggestion.Text))
            return;
        string searchText = _suggestion.Text;

        ObservableCollection<Inline> inlines = new ObservableCollection<Inline>();

        Run run = new();
        while (searchText.Contains("<b>"))
            {
            string initialText = searchText.Substring(0, searchText.IndexOf("<b>"));
            run.Text = initialText;
            inlines.Add(run);
            searchText = searchText.Substring(searchText.IndexOf("<b>") + "<b>".Length);
            string boldText = searchText;
            if (searchText.Contains("</b>"))
                boldText = searchText.Substring(0, searchText.IndexOf("</b>"));
            run = new Run
            {
                FontWeight = FontWeights.Bold,
                Text = boldText
            };
            inlines.Add(run);
            searchText = searchText.Substring(searchText.IndexOf("</b>") + "</b>".Length);
            }
        run = new Run
        {
            Text = searchText
        };
        inlines.Add(run);
        SearchSuggestionInlines = inlines;
        }

虽然以下内容已添加到视图中,

<TextBlock controls:TextBlockExtensions.BindableInlines="{Binding Path=SearchSuggestionInlines, Mode=OneWay}" TextWrapping="NoWrap" TextTrimming="CharacterEllipsis" ToolTip="{Binding Path=SearchSuggestionText, Mode=OneWay}"/>

此致,
奥马尔