My application stores many small snippets of information in docx format. The individual information snippets must be stored internally in a way that can be easily accessed as a byte array (IList<byte> and ToArray() works). Another requirement is that the application be able to collate snippets into a document which can be exported.
I am able to use a DocxFormatProvider to import individual snippets to a RadFlowDocument, and can then use the Merge method of RadFlowDocument as necessary to achieve the desired result.
However, I am unable to import a snippet that is the result of the Merge method, if that snippet has been edited from inside a RadRichTextBox. Below is code to reproduce the issue.
MainWindow.xaml:
MainWindow.xaml.cs:
Here are the steps to follow to reproduce the issue:
1) Open a docx file by clicking "Import"
2) Append a second docx file by clicking "Merge"
3) Edit the resulting document inside the RTB.
4) Append a third docx file by clicking "Merge"
An exception will be thrown at line 86 in MainWindow.xaml.cs by:
RadFlowDocument existingDocument = provider.Import(Data.ToArray());
The exception is:
"The given key was not present in the dictionary."
Also, I would be very grateful for any information about how I might remove the line break inserted between documents by the Merge method. When merging documents, there does not appear to be any line break in the RadRichTextBox. However, after clicking "Export" and saving the document, line breaks appear between the merged documents in Word.
I am able to use a DocxFormatProvider to import individual snippets to a RadFlowDocument, and can then use the Merge method of RadFlowDocument as necessary to achieve the desired result.
However, I am unable to import a snippet that is the result of the Merge method, if that snippet has been edited from inside a RadRichTextBox. Below is code to reproduce the issue.
MainWindow.xaml:
<Window x:Class="TelerikDocxManipulationTest.MainWindow" xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" Title="MainWindow" Height="800" Width="1000"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition Height="*" /> </Grid.RowDefinitions> <telerik:DocxDataProvider x:Name="DocxDataProvider" RichTextBox="{Binding ElementName=DataInput}" Docx="{Binding Data, Mode=TwoWay}"> </telerik:DocxDataProvider> <StackPanel Orientation="Horizontal"> <Button Grid.Column="1" Width="100" Margin="10,0,0,0" Click="Import"> <TextBlock> Import </TextBlock> </Button> <Button Grid.Column="1" Width="100" Margin="10,0,0,0" Click="Merge"> <TextBlock> Merge </TextBlock> </Button> <Button Grid.Column="1" Width="100" Margin="10,0,0,0" Click="Export"> <TextBlock> Export </TextBlock> </Button> </StackPanel> <telerik:RadRichTextBox x:Name="DataInput" Grid.Row="1" IsSpellCheckingEnabled="False" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Visible" LayoutMode="Paged"/> </Grid></Window>MainWindow.xaml.cs:
using Microsoft.Win32;using System;using System.Collections.Generic;using System.ComponentModel;using System.IO;using System.Linq;using System.Windows;using Telerik.Windows.Documents.Flow.FormatProviders.Docx;using Telerik.Windows.Documents.Flow.Model;using Telerik.Windows.Documents.Flow.Model.Collections;namespace TelerikDocxManipulationTest{ /// <summary> /// Interaction logic for MainWindow.xaml /// </summary> public partial class MainWindow : Window, INotifyPropertyChanged { public MainWindow() { InitializeComponent(); DataContext = this; } /// <summary> /// Telerik DocxFormatProvider /// </summary> private DocxFormatProvider provider = new DocxFormatProvider(); /// <summary> /// The binary data for the docx file /// </summary> private IList<byte> mData = new List<byte>(); public IList<byte> Data { get { return mData; } set { mData = value; OnPropertyChanged("Data"); } } /// <summary> /// Import a docx file from disk /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Import(object sender, RoutedEventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "docx files (*.docx)|*.docx"; dialog.RestoreDirectory = true; if (dialog.ShowDialog() == true) { try { Data = File.ReadAllBytes(dialog.FileName).ToList(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } /// <summary> /// Merge the current document with a docx document from disk /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Merge(object sender, RoutedEventArgs e) { OpenFileDialog dialog = new OpenFileDialog(); dialog.Filter = "docx files (*.docx)|*.docx"; dialog.RestoreDirectory = true; if (dialog.ShowDialog() == true) { try { RadFlowDocument existingDocument = provider.Import(Data.ToArray()); RadFlowDocument mergeDocument = provider.Import(dialog.OpenFile()); existingDocument.Merge(mergeDocument); Data = provider.Export(existingDocument).ToList(); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } /// <summary> /// Export the current file data to disk /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void Export(object sender, RoutedEventArgs e) { SaveFileDialog dialog = new SaveFileDialog(); dialog.DefaultExt = "docx"; dialog.Filter = "docx files (*.docx)|*.docx"; dialog.RestoreDirectory = true; if (dialog.ShowDialog() == true) { using (Stream output = dialog.OpenFile()) { try { output.Write(Data.ToArray(), 0, Data.Count); MessageBox.Show("Document exported."); } catch (Exception ex) { MessageBox.Show(ex.Message); } } } } #region INotifiedProperty Block public event PropertyChangedEventHandler PropertyChanged; protected void OnPropertyChanged(string propertyName) { PropertyChangedEventHandler handler = PropertyChanged; if (handler != null) { handler(this, new PropertyChangedEventArgs(propertyName)); } } #endregion }}Here are the steps to follow to reproduce the issue:
1) Open a docx file by clicking "Import"
2) Append a second docx file by clicking "Merge"
3) Edit the resulting document inside the RTB.
4) Append a third docx file by clicking "Merge"
An exception will be thrown at line 86 in MainWindow.xaml.cs by:
RadFlowDocument existingDocument = provider.Import(Data.ToArray());
The exception is:
"The given key was not present in the dictionary."
Also, I would be very grateful for any information about how I might remove the line break inserted between documents by the Merge method. When merging documents, there does not appear to be any line break in the RadRichTextBox. However, after clicking "Export" and saving the document, line breaks appear between the merged documents in Word.