簡體   English   中英

WPF Richtextbox FontFace/FontSize

[英]WPF Richtextbox FontFace/FontSize

我目前正在嘗試在 WPF 項目中創建一些基本的文字處理器功能。 我正在使用 RichTextBox 並且知道所有的 EditingCommands(ToggleBold、ToggleItalic...等)。 我堅持的事情是允許用戶更改字體大小和字體,就像在 MS Office 中一樣,其中僅選定文本的值會更改,如果沒有選定的文本,則當前插入符號 position 的值將更改。 我已經想出了相當多的代碼來讓它工作,但是我遇到了沒有選擇文本的問題。 這是我為 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);

所以我的問題是我應該如何做 go 有沒有更好/更方便的方法來做到這一點? 我的一個想法是我需要在段落中插入一個新的內聯,但我不知道該怎么做。 任何幫助表示贊賞。 謝謝你。

我已經解決了這個問題:

TextRange r = new TextRange(richtextbox.Selection.Start, richtextbox.Selection.End);
r.ApplyPropertyValue(TextElement.FontSizeProperty, value);

我只是遇到了完全相同的問題。 正如本德威所說,我能夠使用 TextElement.FontSizeProperty 。 但是,它仍然無法正常工作。 在查看下面鏈接的項目后,我發現我仍然做錯了什么。 我沒有將焦點重新設置到 RichTextBox ... 下面項目的作者不需要這樣做,因為他們使用的是功能區 combobox。 使用常規的 combobox,在您使用 select 字體后,它確實會更改 RichTextBox 中選擇的字體,但它會將焦點從 RTB 上移開。 當您單擊 RTB 以獲取焦點並開始輸入時,您將獲得一個新的選擇 object,在這種情況下,字體將恢復為 RTB 本身的默認字體。

http://www.codeplex.com/WPFRichEditorLibrary

@sub-jp 是對的,您需要將焦點設置回RichTextBox ,否則您將更改一個選擇的屬性,但是當您單擊返回文本框時,您將獲得一個具有現有字體的新選擇. 嘗試將您的代碼更改為:

TextSelection text = richTextBox.Selection;

richTextBox.Focus();

text.ApplyPropertyValue(RichTextBox.FontSizeProperty, value);

...然后它應該在突出顯示文本和沒有突出顯示的情況下都能正常工作。

或者,如此處所建議的,您可以將 ComboBox 的Focusable屬性設置為False ,以完全避免此問題。

嘗試這個

var range = new TextRange( richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd );
range.ApplyPropertyValue( TextElement.FontSizeProperty, value );

問題是您必須在選擇新的 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);            

    }

如果我理解正確的話,我遇到了類似的問題。 我嘗試搜索大量接近但對我不太有用的各種答案。 我的問題是字體更改對於明確選擇的文本效果很好,但是如果沒有選定的文本,並且字體大小發生了更改,則輸入的以下文本將恢復為默認字體大小。 這是我終於想出來的,試一試,讓我知道它是否適用於其他人:

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

如果您正在處理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跳躍或下沉,請嘗試在每次正確設置CaretPosition之前檢查Caret是否位於Paragraph的末尾。 像這樣的東西會起作用:

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

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM