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
|
{
|
/// <summary>
|
/// UserControl1.xaml 的交互逻辑
|
/// </summary>
|
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 Source=\"data:image/jpg;base64,{base64}\" />";
|
// 替换原有的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 picMaxWidth = DProperty.GetPicMaxWidth(this);
|
double width = img.PixelWidth;
|
if (picMaxWidth > 0 && width > picMaxWidth)
|
{
|
width = picMaxWidth;
|
}
|
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 = $"<Image Source=\"data:image/jpg;base64,{base64}\" />";
|
//var imgContainer = new InlineUIContainer(imgXaml);
|
//pointer.Paragraph.Inlines.Add(imgXaml);
|
|
/// 下面注释的这段是直接插入新段落的写法
|
//var imgContainer = new BlockUIContainer(insertImg);
|
//this.richTextBox.CaretPosition.InsertParagraphBreak();
|
//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);
|
}
|
}
|
|
/// <summary>
|
/// 富文本 Ctrl+V 事件
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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;
|
}
|
}
|
}
|
|
/// <summary>
|
/// 复制菜单
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
private void Copy_Click(object sender, RoutedEventArgs e)
|
{
|
richTextBox.Copy();
|
}
|
|
/// <summary>
|
/// 粘贴菜单
|
/// </summary>
|
/// <param name="sender"></param>
|
/// <param name="e"></param>
|
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));
|
|
|
FileStream pngfs = new FileStream("C:\\1.png", FileMode.OpenOrCreate);
|
|
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字符串
|
}
|
|
//be.Save(pngfs);
|
//pngfs.Close();
|
}
|
}
|
}
|