RichTextBox и редактирование документов

Последнее обновление: 29.02.2016

Если для отображения потокового документа в WPF предназначены элементы FlowDocumentPageViewer, FlowDocumentScrollViewer и FlowDocumentReader, то для его редактирования применяется элемент RichTextBox.

Чтобы загрузить в RichTextBox файл, мы можем воспользоваться методом XamlReader.Load, который загружает xaml-содержимое. Однако чтобы загрузить иное содержимое, например, файлы rtf или простой текст, нам надо воспользоваться классом TextRange, который сам преобразует документ из формата rtf в объект FlowDocument.

Для работы с RichTextBox определим следующую разметку:

<Window x:Class="DocumentsApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:DocumentsApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Height" Value="25" />
            <Setter Property="Width" Value="80" />
            <Setter Property="Margin" Value="25 5 25 5" />
        </Style>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*" />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <RichTextBox x:Name="docBox" />
        <StackPanel Orientation="Horizontal" Grid.Row="1" HorizontalAlignment="Center">
            <Button Content="Сохранить" Click="Save_Click" />
            <Button Content="Загрузить"  Click="Load_Click" />
        </StackPanel>
    </Grid>
</Window>

А в файле кода установим обработчики нажатия кнопок:

using Microsoft.Win32;
using System.IO;
using System.Windows;
using System.Windows.Documents;

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

        private void Save_Click(object sender, RoutedEventArgs e)
        {
            SaveFileDialog sfd = new SaveFileDialog();
            sfd.Filter = "Text Files (*.txt)|*.txt|RichText Files (*.rtf)|*.rtf|XAML Files (*.xaml)|*.xaml|All files (*.*)|*.*";
            if (sfd.ShowDialog() == true)
            {
                TextRange doc = new TextRange(docBox.Document.ContentStart, docBox.Document.ContentEnd);
                using (FileStream fs = File.Create(sfd.FileName))
                {
                    if (Path.GetExtension(sfd.FileName).ToLower() == ".rtf")
                        doc.Save(fs, DataFormats.Rtf);
                    else if (Path.GetExtension(sfd.FileName).ToLower() == ".txt")
                        doc.Save(fs, DataFormats.Text);
                    else
                        doc.Save(fs, DataFormats.Xaml);
                }
            }
        }

        private void Load_Click(object sender, RoutedEventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "RichText Files (*.rtf)|*.rtf|All files (*.*)|*.*";

            if (ofd.ShowDialog() == true)
            {
                TextRange doc = new TextRange(docBox.Document.ContentStart, docBox.Document.ContentEnd);
                using (FileStream fs = new FileStream(ofd.FileName, FileMode.Open))
                {
                    if (Path.GetExtension(ofd.FileName).ToLower() == ".rtf")
                        doc.Load(fs, DataFormats.Rtf);
                    else if (Path.GetExtension(ofd.FileName).ToLower() == ".txt")
                        doc.Load(fs, DataFormats.Text);
                    else
                        doc.Load(fs, DataFormats.Xaml);
                }
            }
        }
    }
}

Чтобы открыть файл, мы используем класс TextRange. Конструктор этого класса принимает в качестве параметров начальную и конечную точки документа, которые определяют ту часть документа, которую надо изменить. В данном случае мы изменяем весь документ, поэтому указываем в качестве начальной точки начало документа, а в качестве конечной - конец документа.

Далее мы получаем поток, связанный с выбранным файлом и загружаем его в RichTextBox с помощью метода Load - Load(fs,DataFormats.Rtf). Здесь мы указываем значение перечисления DataFormats, которое позволяет нам правильно преобразовать тип документа в объект FlowDocument.

При сохранении документа мы также создаем объект TextRange, который в конструкторе принимает начало и конец документа. И затем используем метод Save для сохранения документа в нужный формат.

RichTextBox в WPF

Но при работе с документами xaml в данном случае надо учитывать, что TextRange загружает и сохраняет документ с корневым узлом Section. И если у нас содержимое файла, который надо загрузить, отличается по структуре, то опять же для загрузки xaml-файлов мы можем использовать другой способ:

FlowDocument document = System.Windows.Markup.XamlReader.Load(fs) as FlowDocument;
if (document != null)
    docBox.Document = document;
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850