我目前正在尝试在WPF项目中创建一些基本的文字处理器功能。我正在使用RichTextBox并且知道所有的EditingCommands(ToggleBold,ToggleItalic等等)。我坚持的事情是允许用户像在MS Office中那样更改字体大小和字体,其中值仅针对所选文本进行更改,如果没有选定文本,则值将更改为当前插入位置。 我已经提出了相当数量的代码来使这个工作,但我没有选择文本的问题。以下是我为RichTextBox.Selection所做的工作。
TextSelection text = richTextBox.Selection;
if (text.IsEmpty)
{
//doing this will change the entire word that the current caret position
//is on which is not the desire/expected result.
text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);
}
else
//This works as expected.
text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);
所以我的问题是我应该怎么做呢?有没有更好/更方便的方法来做到这一点? 我有一个想法是,我需要在段落中插入一个新的内联,但我无法弄清楚如何做到这一点。任何帮助表示赞赏。谢谢。
答案 0 :(得分:2)
我刚才遇到了同样的问题。 bendewey说,我能够使用TextElement.FontSizeProperty。但是,它仍然没有正常工作。在查看下面链接的项目后,我发现我还在做错事。我没有将焦点设置回RichTextBox ...下面的项目作者不需要这样做,因为他们使用的是一个功能区组合框。使用常规组合框,在选择字体后,它实际上会更改RichTextBox中选择的字体,但它会将焦点从RTB中移开。当您单击RTB以获得焦点并开始键入时,您有一个新的选择对象,在这种情况下,字体将恢复为RTB本身的默认字体。
答案 1 :(得分:1)
试试这个
var range = new TextRange( richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd );
range.ApplyPropertyValue( TextElement.FontSizeProperty, value );
答案 2 :(得分:1)
@ sub-jp是对的,你需要将焦点设置回RichTextBox
,否则你将改变一个选择的属性,但当你点击回到文本框时,你会得到使用现有字体的新选择。尝试将代码更改为:
TextSelection text = richTextBox.Selection;
richTextBox.Focus();
text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);
...然后它应该在突出显示文本和没有文本时正常工作。
或者,as suggested here,您可以将ComboBox的Focusable
属性设置为False
,以完全避免此问题。
答案 3 :(得分:1)
我已经解决了这个问题:
TextRange r = new TextRange(richtextbox.Selection.Start, richtextbox.Selection.End);
r.ApplyPropertyValue(TextElement.FontSizeProperty, value);
答案 4 :(得分:0)
如果我理解正确的话,我遇到了类似的问题。我试着搜索各种各样的答案,这些答案很接近但对我来说并不适用。我的问题是字体更改适用于明确选择的文本,但如果没有选定的文本,并且字体大小已更改,则输入的以下文本将恢复为默认的fontsize。这是我最终想出来的,试一试,让我知道它是否适用于其他任何人:
public static void SetFontSize(RichTextBox target, double value)
{
// Make sure we have a richtextbox.
if (target == null)
return;
// Make sure we have a selection. Should have one even if there is no text selected.
if (target.Selection != null)
{
// Check whether there is text selected or just sitting at cursor
if (target.Selection.IsEmpty)
{
// Check to see if we are at the start of the textbox and nothing has been added yet
if (target.Selection.Start.Paragraph == null)
{
// Add a new paragraph object to the richtextbox with the fontsize
Paragraph p = new Paragraph();
p.FontSize = value;
target.Document.Blocks.Add(p);
}
else
{
// Get current position of cursor
TextPointer curCaret = target.CaretPosition;
// Get the current block object that the cursor is in
Block curBlock = target.Document.Blocks.Where
(x => x.ContentStart.CompareTo(curCaret) == -1 && x.ContentEnd.CompareTo(curCaret) == 1).FirstOrDefault();
if (curBlock != null)
{
Paragraph curParagraph = curBlock as Paragraph;
// Create a new run object with the fontsize, and add it to the current block
Run newRun = new Run();
newRun.FontSize = value;
curParagraph.Inlines.Add(newRun);
// Reset the cursor into the new block.
// If we don't do this, the font size will default again when you start typing.
target.CaretPosition = newRun.ElementStart;
}
}
}
else // There is selected text, so change the fontsize of the selection
{
TextRange selectionTextRange = new TextRange(target.Selection.Start, target.Selection.End);
selectionTextRange.ApplyPropertyValue(TextElement.FontSizeProperty, value);
}
}
// Reset the focus onto the richtextbox after selecting the font in a toolbar etc
target.Focus();
}
答案 5 :(得分:0)
问题是,在选择新的FontFamily或字体大小后,您必须将焦点设置回Rich Textbox:
//When Font Size is changed
private void rbngFontSize_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
rtbMain.Focus(); // This part is what fixes the issue, just make sure it is set before ApplyPropertyValue method.
try
{
ApplyPropertyValueToSelectedText(TextElement.FontSizeProperty, e.AddedItems[0]);
}
catch { };
}
//When FontFamily is changed
private void rbngFontFamily_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
FontFamily editValue = (FontFamily)e.AddedItems[0];
rtbMain.Focus(); // This part is what fixes the issue, just make sure it is set before ApplyPropertyValue method.
ApplyPropertyValueToSelectedText(TextElement.FontFamilyProperty, editValue);
}
答案 6 :(得分:0)
如果您正在处理OnTextInput
,这很容易解决。
protected override void OnTextInput(TextCompositionEventArgs e)
{
TextRange range = new TextRange(this.Selection.Start, this.Selection.End);
// Doesn't matter whether the selection is empty or not, it should be
// replaced with something new, and with the right formatting
range.Text = e.Text;
// Now nothing else would get affected...
range.ApplyPropertyValue(TextElement.FontFamilyProperty, value);
this.CaretPosition = range.End;
e.Handled = true; // You might not need this line :)
}
编辑:
将CaretPosition
设置为TextRange
的末尾,有时可能会导致Caret
错误对齐。我的RichTextBox
进行了大量BaselineAlignment
调整,这可能是导致我的问题。但是,如果您遇到任何有趣的Caret
跳转或接收,请在每次正确设置Caret
之前检查Paragraph
是否在CaretPosition
的末尾。像这样的东西会起作用:
TextRange test = new TextRange(range.End, range.End.Paragraph.ContentEnd);
bool IsAtEnd = test.IsEmpty || String.IsNullOrEmpty(test.Text) || test.Text == "\r\n";
// Now we know whether the Caret is still in the middle of the text or not
// This part corrects the Caret glitch! :)
if (!IsAtEnd)
this.CaretPosition = range.End;
else
this.CaretPosition = range.Start.GetNextContextPosition(LogicalDirection.Forward);
我知道我的答案已经很晚了,但希望我能帮助别人。干杯!