RichTextBox WPF将内容限制在一行中



我需要用粗体显示字符串的部分。由于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;
}
}

关于如何在行尾前实现字符省略号的任何建议。

谨致问候,Umar

您应该能够使用带文本换行和文本修剪的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集合的解决方案。字符串中粗体区域的数量在运行时决定。因此,我创建了一个依赖属性。跟随对我来说很有效。将来为了他人的利益而分享。

TextBlockExtension.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;
}

当以下内容被添加到View时,

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

问候,
Umar

最新更新