【问题标题】:RichTextBox WPF limit content in one lineRichTextBox WPF 将内容限制在一行
【发布时间】:2021-11-17 18:41:56
【问题描述】:

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

    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 有一个 TextBlock.Inlines 属性,您可以使用它来组成运行和段落的显示文本类似于 RichTextBox 的元素。因此,如果您不关心文本输入,您也可以在 TextBlock 中使用一些更复杂的文本格式。

标签: c# wpf richtextbox


【解决方案1】:

您应该能够使用 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 元素。

【讨论】:

    【解决方案2】:

    感谢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}"/>
    

    问候,
    奥马尔

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-18
      • 2011-10-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多