6

我目前正在尝试在 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);

所以我的问题是我应该怎么做呢?有没有更好/更方便的方法来做到这一点?我的一个想法是我需要在段落中插入一个新的内联,但我不知道该怎么做。任何帮助表示赞赏。谢谢你。

4

7 回答 7

4

我已经解决了这个问题:

TextRange r = new TextRange(richtextbox.Selection.Start, richtextbox.Selection.End);
r.ApplyPropertyValue(TextElement.FontSizeProperty, value);
于 2014-10-22T16:58:56.877 回答
2

我只是遇到了完全相同的问题。正如本德威所说,我能够使用 TextElement.FontSizeProperty 。但是,它仍然无法正常工作。在查看下面链接的项目后,我发现我仍然做错了什么。我没有将焦点重新设置到 RichTextBox ... 下面项目的作者不需要这样做,因为他们使用的是功能区组合框。使用常规组合框,在您选择一种字体后,它确实会更改 RichTextBox 中选择的字体,但它会将焦点从 RTB 上移开。当您单击 RTB 以获取焦点并开始输入时,您将拥有一个新的选择对象,在这种情况下,字体将恢复为 RTB 本身的默认字体。

http://www.codeplex.com/WPFRichEditorLibrary

于 2009-12-22T21:37:39.223 回答
1

@sub-jp 是对的,您需要将焦点设置回RichTextBox,否则您将更改一个选择的属性,但是当您单击返回文本框时,您将获得一个具有现有字体的新选择。尝试将您的代码更改为:

TextSelection text = richTextBox.Selection;

richTextBox.Focus();

text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);

...然后它应该在突出显示文本和没有突出显示的情况下都能正常工作。

或者,如此处所建议的,您可以将FocusableComboBox 的属性设置为False,以完全避免此问题。

于 2013-05-28T09:50:22.020 回答
1

尝试这个

var range = new TextRange( richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd );
range.ApplyPropertyValue( TextElement.FontSizeProperty, value );
于 2009-03-23T17:31:38.117 回答
0

如果我理解正确的话,我遇到了类似的问题。我尝试搜索大量接近但对我不太有用的各种答案。我的问题是字体更改对于明确选择的文本效果很好,但是如果没有选定的文本,并且字体大小发生了更改,则输入的以下文本将恢复为默认字体大小。这是我终于想出来的,试一试,让我知道它是否适用于其他人:

    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();
    }
于 2010-11-16T21:12:02.637 回答
0

问题是您必须在选择新的 FontFamily 或 Font Size 后将焦点设置回富文本框:

//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);            

    }
于 2015-06-09T14:58:46.207 回答
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结束时。像这样的东西会起作用:ParagraphCaretPosition

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);

我知道我的回答很晚了,但希望我帮助了别人。干杯!

于 2017-07-27T07:06:45.240 回答