Если для отображения потокового документа в 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 для сохранения документа в нужный формат.
Но при работе с документами xaml в данном случае надо учитывать, что TextRange загружает и сохраняет документ с корневым узлом Section
.
И если у нас содержимое файла, который надо загрузить, отличается по структуре, то опять же для загрузки xaml-файлов мы можем использовать другой способ:
FlowDocument document = System.Windows.Markup.XamlReader.Load(fs) as FlowDocument; if (document != null) docBox.Document = document;