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();
}
}
}
}