using Microsoft.Win32; using System; using System.ComponentModel; using System.Diagnostics; using System.IO; using System.Reflection; using System.Runtime.InteropServices.ComTypes; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Markup; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Media.Media3D; namespace PdmSwPlugin.UI { /// /// UserControl1.xaml 的交互逻辑 /// public partial class CustomRichBox : UserControl { public CustomRichBox() { InitializeComponent(); } private void Color_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (sender == null) { return; } var item = sender as ComboBox; var buttonType = item.Name == "combBackground" ? "Background" : "Foreground"; if (item != null) { var color = (item.SelectedItem as ComboBoxItem).Background; SetColor(buttonType, color); } } private void FontSize_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (sender == null) { return; } var item = sender as ComboBox; if (item != null) { string sizeStr = (item.SelectedItem as ComboBoxItem).Content.ToString(); try { double size = double.Parse(sizeStr); var textSelection = this.richTextBox?.Selection; if (textSelection == null) return; textSelection.ApplyPropertyValue(TextElement.FontSizeProperty, size); } catch { } } } private void SetColor(string buttonType, Brush brush) { var textSelection = this.richTextBox.Selection; if (textSelection == null) { return; } if (buttonType == "Background") { var propertyValue = textSelection.GetPropertyValue(TextElement.BackgroundProperty); var bgBrush = (Brush)propertyValue; if (bgBrush == brush) { textSelection.ApplyPropertyValue(TextElement.BackgroundProperty, Colors.White); } else { textSelection.ApplyPropertyValue(TextElement.BackgroundProperty, brush); } } if (buttonType == "Foreground") { var propertyValue = textSelection.GetPropertyValue(TextElement.ForegroundProperty); var foreground = (Brush)propertyValue; if (foreground == brush) { textSelection.ApplyPropertyValue(TextElement.ForegroundProperty, Colors.Black); } else { textSelection.ApplyPropertyValue(TextElement.ForegroundProperty, brush); } } richTextBox.Focus(); } private void Setting_Click(object sender, System.Windows.RoutedEventArgs e) { var textSelection = this.richTextBox.Selection; Button button = sender as Button; if (button == null) return; string buttonType = button.Tag.ToString(); if (buttonType == "StrikeLine") { var propertyValue = textSelection.GetPropertyValue(Inline.TextDecorationsProperty); var textDecorationCollection = (TextDecorationCollection)propertyValue; if (textDecorationCollection == TextDecorations.Strikethrough) { textSelection.ApplyPropertyValue(Inline.TextDecorationsProperty, null); } else { textSelection.ApplyPropertyValue(Inline.TextDecorationsProperty, TextDecorations.Strikethrough); } } else if (buttonType == "Super") { var propertyValue = textSelection.GetPropertyValue(Inline.BaselineAlignmentProperty); var supper = (BaselineAlignment)propertyValue; if (supper == BaselineAlignment.Superscript) { textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Top); } else { textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Superscript); } } else if (buttonType == "Sub") { var propertyValue = textSelection.GetPropertyValue(Inline.BaselineAlignmentProperty); var sub = (BaselineAlignment)propertyValue; if (sub == BaselineAlignment.Subscript) { textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Top); } else { textSelection.ApplyPropertyValue(Inline.BaselineAlignmentProperty, BaselineAlignment.Subscript); } } else if (buttonType == "fontSize") { } else if (buttonType == "Image") { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Title = "请选择需要插入的图片"; openFileDialog.Filter = "图片文件|*.png"; bool? flag = openFileDialog.ShowDialog(); if (flag == true) { try { var fileName = openFileDialog.FileName; var imgSource = new BitmapImage(new Uri(fileName)); InsertPicToRichBox(imgSource); /*double imgWidth = imgSource.Width, imgHeight = imgSource.Height; if (imgWidth > richTextBox.ActualWidth) { double rate = Math.Floor(richTextBox.ActualWidth / imgWidth); imgWidth = imgWidth * rate; imgHeight = imgHeight * rate; } var img = new Image() { Source = imgSource, Stretch = Stretch.Uniform, Width = this.richTextBox.ActualWidth - 50 }; var imgContainer = new BlockUIContainer(img); this.richTextBox.CaretPosition.InsertParagraphBreak(); this.richTextBox.Document.Blocks.InsertAfter(this.richTextBox.CaretPosition.Paragraph, imgContainer);*/ } catch (Exception ex) { MessageBox.Show("不支持的图片格式"); } } } else if (buttonType == "Print") { PrintDialog pd = new PrintDialog(); if ((pd.ShowDialog() == true)) { //use either one of the below pd.PrintVisual(this.richTextBox as Visual, "打印富文本1"); pd.PrintDocument((((IDocumentPaginatorSource)this.richTextBox.Document).DocumentPaginator), "打印富文本2"); } } richTextBox.Focus(); } private string ImageToBase64(BitmapSource image) { JpegBitmapEncoder encoder = new JpegBitmapEncoder(); // 使用JPEG编码 encoder.Frames.Add(BitmapFrame.Create(image)); using (MemoryStream ms = new MemoryStream()) { encoder.Save(ms); byte[] imageBytes = ms.ToArray(); return Convert.ToBase64String(imageBytes); // 将字节数组转换为Base64字符串 } } public byte[] GetBlob() { var range = new TextRange(richTextBox.Document.ContentStart, richTextBox.Document.ContentEnd); using (MemoryStream memoryStream = new MemoryStream()) { range.Save(memoryStream, DataFormats.XamlPackage); return memoryStream.ToArray(); } } public string GetContent() { FlowDocument flowDoc = richTextBox.Document; // 遍历文档中的所有Block foreach (Block block in flowDoc.Blocks) { if (block is Paragraph) { Paragraph paragraph = block as Paragraph; foreach (Inline inline in paragraph.Inlines) { if (inline is InlineUIContainer) { InlineUIContainer uiContainer = inline as InlineUIContainer; if (uiContainer.Child is Image) { Image image = uiContainer.Child as Image; BitmapSource bitmapSource = image.Source as BitmapSource; string base64 = ImageToBase64(bitmapSource); string imgXaml = $""; // 替换原有的Image对象 uiContainer.Child = new Image() { Source = new BitmapImage(new Uri(imgXaml)) }; } } } } } using (MemoryStream memoryStream = new MemoryStream()) { XamlWriter.Save(flowDoc, memoryStream); memoryStream.Seek(0, SeekOrigin.Begin); using (StreamReader reader = new StreamReader(memoryStream)) { return reader.ReadToEnd(); } } } private void UserControl_Loaded(object sender, RoutedEventArgs e) { fontSizeComb.SelectedIndex = 0; combBackground.SelectedIndex = 0; combForeground.SelectedIndex = 0; } public void LoadFromBlob(byte[] blob) { if (blob == null || blob.Length <= 0) { return; } var range = new TextRange(this.richTextBox.Document.ContentStart, this.richTextBox.Document.ContentEnd); using (var ss = new MemoryStream(blob)) { range.Load(ss, DataFormats.XamlPackage); } } private void InsertPicToRichBox(BitmapSource img) { bool DisableEdit = DProperty.GetDisableEdit(this); if (DisableEdit) return; try { double pageWidth = richTextBox.Document.PageWidth; //DProperty.GetPicMaxWidth(this); double width = img.PixelWidth; if (double.IsNaN(pageWidth)) { double actWidth = richTextBox.ExtentWidth; if (width > actWidth) { width = pageWidth; } } else if (pageWidth > 0 && width > pageWidth) { width = pageWidth; } TextPointer pointer = richTextBox.CaretPosition; var insertImg = new Image() { Source = img, Stretch = Stretch.Uniform, Width = width }; /// 行内插入图片 //var imgContainer = new InlineUIContainer(insertImg); //pointer.Paragraph.Inlines.Add(imgContainer); //string base64 = ImageToBase64(img); //string imgXaml = $""; //var imgContainer = new InlineUIContainer(imgXaml); //pointer.Paragraph.Inlines.Add(imgXaml); /// 图片另起一行 var imgContainer = new InlineUIContainer(insertImg); pointer.InsertParagraphBreak(); pointer.Paragraph.Inlines.Add(imgContainer); // this.richTextBox.Document.Blocks.InsertAfter(this.richTextBox.CaretPosition.Paragraph, imgContainer); } catch (Exception e) { } } public void ChangeStatus(bool DisableEdit) { if (DisableEdit) { toolBar.Visibility = Visibility.Collapsed; richTextBox.IsReadOnly = true; richTextBox.BorderThickness = new Thickness(0); } else { toolBar.Visibility = Visibility.Visible; richTextBox.IsReadOnly = false; richTextBox.BorderThickness = new Thickness(1); } } /// /// 富文本 Ctrl+V 事件 /// /// /// private void UserControl_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if (e.KeyboardDevice.Modifiers == ModifierKeys.Control && e.Key == Key.V) { if (Clipboard.ContainsImage()) { var img = Clipboard.GetImage(); InsertPicToRichBox(img); e.Handled = true; } } } /// /// 复制菜单 /// /// /// private void Copy_Click(object sender, RoutedEventArgs e) { richTextBox.Copy(); } /// /// 粘贴菜单 /// /// /// private void Paste_Click(object sender, RoutedEventArgs e) { try { if (DProperty.GetDisableEdit(this) == true) { return; } if (Clipboard.ContainsImage()) { var img = Clipboard.GetImage(); InsertPicToRichBox(img); } else { richTextBox.Paste(); } } catch (Exception ex) { } } public void ToBase64Image2() { richTextBox.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); richTextBox.Arrange(new Rect(new Size(richTextBox.ActualWidth, richTextBox.ActualHeight))); // Create a DrawingVisual and use a VisualBrush to render the RichTextBox DrawingVisual visual = new DrawingVisual(); using (DrawingContext context = visual.RenderOpen()) { VisualBrush brush = new VisualBrush(richTextBox); context.DrawRectangle(brush, null, new Rect(new Size(richTextBox.ActualWidth, richTextBox.ActualHeight))); } // Render the DrawingVisual to a RenderTargetBitmap RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap( (int)richTextBox.ActualWidth, (int)richTextBox.ActualHeight, 96d, 96d, PixelFormats.Pbgra32); renderTargetBitmap.Render(visual); // Create a BitmapEncoder to encode the RenderTargetBitmap PngBitmapEncoder pngEncoder = new PngBitmapEncoder(); pngEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (FileStream stream = new FileStream("C:\\Workspace\\test.png", FileMode.OpenOrCreate)) { // Save the encoded PNG image to a memory stream pngEncoder.Save(stream); stream.Flush(); stream.Close(); } /* using (MemoryStream memoryStream = new MemoryStream()) { // Save the encoded PNG image to a memory stream pngEncoder.Save(memoryStream); // Convert the memory stream to a byte array byte[] imageBytes = memoryStream.ToArray(); // Convert the byte array to a Base64 string return Convert.ToBase64String(imageBytes); }*/ } public string ToBase64Image() { //string sss = XamlWriter.Save(richTextBox.Document); //Debug.Print(sss); // Force a measure and arrange of the RichTextBox to ensure all content is rendered //richTextBox.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); //richTextBox.Arrange(new Rect(new Size(richTextBox.ActualWidth, richTextBox.ActualHeight))); //// Render the DrawingVisual to a RenderTargetBitmap //RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap( // (int)richTextBox.ActualWidth, // (int)richTextBox.ActualHeight, // 96d, 96d, PixelFormats.Pbgra32); //FlowDocumentReader reader = new FlowDocumentReader //{ // Document = richTextBox.Document //}; //renderTargetBitmap.Render(reader); //// Create a BitmapEncoder to encode the RenderTargetBitmap //PngBitmapEncoder pngEncoder = new PngBitmapEncoder(); //pngEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); //using (FileStream stream = new FileStream("C:\\Workspace\\test.png",FileMode.OpenOrCreate)) //{ // // Save the encoded PNG image to a memory stream // pngEncoder.Save(stream); // stream.Flush(); // stream.Close(); //} //string sss = XamlWriter.Save(richTextBox.Document); //Debug.Print(sss); // Backup original size var originalWidth = richTextBox.ExtentWidth; var originalHeight = richTextBox.ExtentHeight; //richTextBox.Measure(new Size(Double.PositiveInfinity, Double.PositiveInfinity)); richTextBox.Arrange(new Rect(new Size(originalWidth, originalHeight))); int dpi = 300; // Create a RenderTargetBitmap with the new size RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap( (int)(originalWidth * dpi / 96), (int)(originalHeight * dpi / 96), 300d, 300d, PixelFormats.Default); // Render the control to the RenderTargetBitmap renderTargetBitmap.Render(richTextBox); // Create an encoder (PNG in this case) PngBitmapEncoder pngEncoder = new PngBitmapEncoder(); pngEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); BitmapEncoder be = new PngBitmapEncoder(); be.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); using (MemoryStream ms = new MemoryStream()) { be.Save(ms); byte[] imageBytes = ms.ToArray(); return Convert.ToBase64String(imageBytes); // 将字节数组转换为Base64字符串 } } public byte[] GetBase64Blob(int dpi = 300) { richTextBox.BorderThickness = new Thickness(0); var originalWidth = Math.Max(richTextBox.ExtentWidth, richTextBox.ActualWidth); var originalHeight = Math.Max(richTextBox.ExtentHeight, richTextBox.ActualHeight); richTextBox.Arrange(new Rect(new Size(originalWidth, originalHeight))); // Create a RenderTargetBitmap with the new size RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap( (int)(originalWidth * dpi / 96), (int)(originalHeight * dpi / 96), 300d, 300d, PixelFormats.Default); // Render the control to the RenderTargetBitmap renderTargetBitmap.Render(richTextBox); // Create an encoder (PNG in this case) PngBitmapEncoder pngEncoder = new PngBitmapEncoder(); pngEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); BitmapEncoder be = new PngBitmapEncoder(); be.Frames.Add(BitmapFrame.Create(renderTargetBitmap)); richTextBox.BorderThickness = new Thickness(1); using (MemoryStream ms = new MemoryStream()) { be.Save(ms); return ms.ToArray(); } } } }