格式化在WPF RichTextBox的开头消失

时间:2014-08-05 12:36:42

标签: c# wpf formatting richtextbox rich-text-editor

我正在WPF中制作一个RTF编辑器,其中包含各种格式化选项(粗体,斜体,字体,字体大小等)以及所有可用作魅力的内容。

但是当我启动我的应用程序并选择不同的字体时,一旦我开始输入,字体就会变回原始字体。如果我然后删除所有文本,再次选择一个新字体,新字体就会保留,从现在开始一切都很好。

我在网上找到的其他编辑器中也看到过相同的行为,例如。 http://www.codeproject.com/Articles/50139/WPF-RichTextEditor-with-Toolbar

非常感谢任何克服这一点的暗示,因为这会让我发疯!

这是一个简单的例子,可以解决我的问题:

<Window x:Class="RTFEditor.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<DockPanel LastChildFill="True" FocusManager.FocusedElement="{Binding ElementName=RichTextBox}">
    <ToggleButton x:Name="BtnBold"
                  PreviewGotKeyboardFocus="BtnBold_OnPreviewGotKeyboardFocus"
                  Command="ToggleBold"
                  CommandTarget="{Binding ElementName=RichTextBox}"
                  DockPanel.Dock="Top">Bold</ToggleButton>
    <RichTextBox x:Name="RichTextBox" SelectionChanged="RichTextBox_OnSelectionChanged"/>
</DockPanel>

using System.Windows;
using System.Windows.Documents;
using System.Windows.Input;

namespace RTFEditor
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void RichTextBox_OnSelectionChanged(object sender, RoutedEventArgs e)
        {
            var currentValue = RichTextBox.Selection.GetPropertyValue(TextElement.FontWeightProperty);
            BtnBold.IsChecked = (currentValue != DependencyProperty.UnsetValue) && (currentValue != null && currentValue.Equals(FontWeights.Bold));
        }

        private void BtnBold_OnPreviewGotKeyboardFocus(object sender, KeyboardFocusChangedEventArgs e)
        {
            e.Handled = true;
        }
    }
}

1 个答案:

答案 0 :(得分:0)

受到这篇文章的启发:WPF EditingCommands is not working when RichTextBox is just load/empty?我最终得到了一个由以下方法组成的解决方案(我的RichTextBox名为Editor!):

    private void PrepareEditor(string initalText)
    {
        var run = new Run(initalText);

        if (IsSelectionFormat(TextElement.FontWeightProperty, FontWeights.Bold))
        {
            run.FontWeight = FontWeights.Bold;
        }
        if (IsSelectionFormat(TextElement.FontStyleProperty, FontStyles.Italic))
        {
            run.FontStyle = FontStyles.Italic;
        }
        if (IsSelectionFormat(Inline.TextDecorationsProperty, TextDecorations.Underline))
        {
            run.TextDecorations = TextDecorations.Underline;
        }

        double fontSize;
        if (double.TryParse(CmbFontSize.Text, out fontSize))
            run.FontSize = FontSizeHelper.PxToPt(fontSize);

        if (CmbFontFamily.Text != "")
            run.FontFamily = new FontFamily(CmbFontFamily.Text);

        Editor.Document.Blocks.Clear();
        Editor.Document.Blocks.Add(new Paragraph(run));
    }

    private bool IsSelectionFormat(DependencyProperty formattingProperty, object expectedValue)
    {
        object currentValue = Editor.Selection.GetPropertyValue(formattingProperty);
        var active = (currentValue != DependencyProperty.UnsetValue) && (currentValue != null && currentValue.Equals(expectedValue));
        return active;
    }

    private void Editor_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        // If the editor is empty, the Run element is sometimes missing, so we need to add it and apply any selected formating manually!
        if (Editor.PlainText() == "" && Editor.CaretPosition.GetInsertionPosition(LogicalDirection.Forward).Parent.GetType() != typeof(Run))
        {
            PrepareEditor(e.Text);
            e.Handled = true;
        }
    }

    private void Editor_OnSelectionChanged(object sender, RoutedEventArgs e)
    {
        if (Editor.PlainText().Trim() == "" && Editor.CaretPosition.GetInsertionPosition(LogicalDirection.Forward).Parent.GetType() != typeof(Run))
        {
            PrepareEditor("");
        }

        // More code ...
    }

同意......它看起来像是一个严重的黑客/解决方法,但它是我能找到/想出的最好的解决方案!