相互关联的RichTextbox

using System.Windows.Forms; public class SynchronizedScrollRichTextBox : System.Windows.Forms.RichTextBox { public SynchronizedScrollRichTextBox Synchronized { get; set; } public const int WM_VSCROLL = 0x115; public const int EM_LINESCROLL = 0xB6; protected override void WndProc(ref System.Windows.Forms.Message msg) { if (msg.Msg == WM_VSCROLL || msg.Msg == EM_LINESCROLL) { if (Synchronized != null) { Message message = msg; message.HWnd = Synchronized.Handle; Synchronized.PubWndProc(ref message); } } base.WndProc(ref msg); } public void PubWndProc(ref System.Windows.Forms.Message msg) { base.WndProc(ref msg); } }

思路参考了中文英文多篇资料,没有比较完整的,所以,算原创也不为过。

我的博客向来简单明了,以上代码,复制到你项目中。编译一次,拖到窗体中即可,例如:

拖2个实例,然后在设计界面,分别设置 Synchronized 属性为对方。运行,两个文本框就可以关联起来了。

前端代码为: <GroupBox Header="修改前(点击下方空白处插入截图)" BorderBrush="Gray" VerticalAlignment="Top" Width="310" Height="175"> <RichTextBox x:Name="rtbImages3" VerticalScrollBarVisibility="Disabled" HorizontalScrollBarVisibility="Disabled" PreviewKeyDown="rtbImages3_PreviewKeyDown" Focusable="True" VerticalAlignment="Stretch" IsDocumentEnabled="True" GotFocus="rtbImages3_GotFocus"> <RichTextBox.Resources> <!-- 设置段落样式 --> <Style TargetType="{x:Type Paragraph}"> <Setter Property="Margin" Value="0,0,0,0"/> <Setter Property="Foreground" Value="Gray"/> <Setter Property="FontStyle" Value="Italic"/> <Setter Property="TextAlignment" Value="Center"/> <Setter Property="FontSize" Value="13"/> </Style> <!-- 移除FlowDocument的内边距 --> <Style TargetType="{x:Type FlowDocument}"> <Setter Property="PagePadding" Value="0"/> </Style> <!-- 设置滚动查看器样式 --> <Style TargetType="{x:Type FlowDocumentScrollViewer}"> <Setter Property="Padding" Value="0"/> <Setter Property="VerticalAlignment" Value="Stretch"/> <Setter Property="HorizontalAlignment" Value="Stretch"/> </Style> </RichTextBox.Resources> </RichTextBox> </GroupBox> <DataGrid Grid.Row="0" x:Name="pfDataGrid" AutoGenerateColumns="False" HorizontalAlignment="Stretch" ItemsSource="{Binding DataItems, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" CanUserSortColumns="False" CanUserAddRows="False"> <!--标题居中--> <DataGrid.Resources> <Style TargetType="DataGridColumnHeader"> <Setter Property="HorizontalContentAlignment" Value="Center"/> </Style> </DataGrid.Resources> <!--单元格点击事件--> <DataGrid.CellStyle> <Style TargetType="DataGridCell"> <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown"/> </Style> </DataGrid.CellStyle> <!--标题内容--> <DataGrid.Columns> <DataGridTextColumn Width="0.5*" Header="序号" IsReadOnly="True" Binding="{Binding SerialNumber}"/> <DataGridTextColumn Width="4*" Header="意见内容" IsReadOnly="True" Binding="{Binding OpinionContent}"/> <DataGridTextColumn Width="1.8*" Header="批注时间" IsReadOnly="True" Binding="{Binding AnnotationTime}"/> <DataGridTextColumn Width="*" Header="修改状态" IsReadOnly="True" Binding="{Binding ModifyStatus}" /> <DataGridTextColumn Width="*" Header="批注人员" IsReadOnly="True" Binding="{Binding Annotator}" /> <DataGridTextColumn Width="*" Header="问题性质" IsReadOnly="True" Binding="{Binding ProblemNature}" /> </DataGrid.Columns> </DataGrid>后端代码为: private void PasteImageToRichTextBox() { if (!Clipboard.ContainsImage()) { MessageBox.Show("剪贴板中没有图片"); return; } Dispatcher.Invoke(() => { try { // 清除提示文本 RemoveHintText(); // 图片保存路径 string ImageSavePath = "C:/ProgramData/EasyBIM/Proofread/"; // 确保目录存在 if (!Directory.Exists(ImageSavePath)) { Directory.CreateDirectory(ImageSavePath); } // 生成唯一文件名 string timestamp = DateTime.Now.ToString("yyyyMMddHHmmss"); string fileName = $"Image_{timestamp}.png"; string filePath = System.IO.Path.Combine(ImageSavePath, fileName); // 直接从剪贴板获取BitmapSource BitmapSource clipboardImage = Clipboard.GetImage(); if (clipboardImage == null) return; // 直接使用BitmapFrame创建BitmapImage BitmapImage bitmapImage; using (MemoryStream stream = new MemoryStream()) { // 使用BmpBitmapEncoder替代PngBitmapEncoder解决兼容性问题 BmpBitmapEncoder encoder = new BmpBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(clipboardImage)); encoder.Save(stream); stream.Position = 0; bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; bitmapImage.StreamSource = stream; bitmapImage.EndInit(); } // 计算缩放比例 double scaleRatio = Math.Min( MaxImageWidth / bitmapImage.PixelWidth, MaxImageHeight / bitmapImage.PixelHeight ); scaleRatio = Math.Min(scaleRatio, 1.0); // 确保不放大图片 // 创建图像控件 var imageControl = new System.Windows.Controls.Image { Source = bitmapImage, Width = bitmapImage.PixelWidth * scaleRatio, Height = bitmapImage.PixelHeight * scaleRatio, Stretch = Stretch.Uniform, Margin = new Thickness(0, 5, 0, 5) }; // 创建容器 Border imageBorder = new Border { Child = imageControl, BorderBrush = Brushes.LightGray, BorderThickness = new Thickness(1), CornerRadius = new CornerRadius(4), Background = Brushes.White, Padding = new Thickness(2) }; // 创建InlineUIContainer InlineUIContainer container = new InlineUIContainer(imageBorder) { BaselineAlignment = BaselineAlignment.Center // 确保垂直居中 }; // 获取当前段落 Paragraph currentParagraph = rtbImages3.CaretPosition.Paragraph ?? new Paragraph(); // 如果是空文档则添加新段落 if (rtbImages3.Document.Blocks.Count == 0) { rtbImages3.Document.Blocks.Add(currentParagraph); } // 添加图片到段落 currentParagraph.Inlines.Add(container); // 设置新光标位置 rtbImages3.CaretPosition = container.ElementEnd; // 使用高保真方式保存原始图片 using (FileStream fileStream = new FileStream(filePath, FileMode.Create)) { PngBitmapEncoder encoder = new PngBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(clipboardImage)); //使用原始剪贴板图片 encoder.Save(fileStream); }} catch (Exception ex) { MessageBox.Show($"图片粘贴失败: {ex.Message}"); } });}private T FindVisualParent<T>(DependencyObject child) where T : DependencyObject { while (child != null && !(child is T)) { child = VisualTreeHelper.GetParent(child); } return child as T; } /// <summary> /// 获取单元格的数据源集合中的索引 /// </summary> /// <param name="cell"></param> /// <returns></returns> private int GetRowIndex(DataGridCell cell) { var item = cell.DataContext;//获取行的绑定数据的对象 var collection = pfDataGrid.ItemsSource as IList; return collection?.IndexOf(item) ?? -1; } /// <summary> /// 更新数据项在界面的序号 /// </summary> /// <param name="DataItems"></param> public void RenewalNum(ObservableCollection<ProofreadListModel> DataItems) { for (int i = 0; i < pfviewModel.DataItems.Count; i++) { pfviewModel.DataItems[i].SerialNumber = i + 1; } } 怎么样将richtextbox中保存的图片与datagrid中的点击“意见内容”相互关联
09-10
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值