为RichTextBox添加带ResizeAdorner的图片时消失,该如何解决?
为RichTextBox的FlowDocument添加带ResizeAdorner的图片
问题说明
向RichTextBox的FlowDocument中添加图片时,直接用ResizeAdorner包裹Image并放入BlockUIContainer后图片消失,原始可运行代码与失效代码如下:
原始可正常运行的代码
public ICommand ImageCommand { get; set; } private bool CanImageExecute(object parameter) => true; private void OnImageExecute(object parameter) { var file = new Microsoft.Win32.OpenFileDialog(); file.ShowDialog(); if(System.IO.Path.GetExtension(file.FileName).ToLower() is ".png" || System.IO.Path.GetExtension(file.FileName).ToLower() is ".jpg") { var BitMapImage = new BitmapImage(); BitMapImage.BeginInit(); BitMapImage.StreamSource = new MemoryStream(File.ReadAllBytes(file.FileName)); BitMapImage.EndInit(); if (_TextSelected is null) return; if (TextSelected.End.Paragraph is null) FileSystem.FileCurent.Blocks.Add(new Paragraph()); FileSystem.FileCurent.Blocks.InsertBefore(TextSelected.End.Paragraph, new BlockUIContainer(new Image { Source = BitMapImage})); } }
包裹ResizeAdorner后失效的代码
public ICommand ImageCommand { get; set; } private bool CanImageExecute(object parameter) => true; private void OnImageExecute(object parameter) { var file = new Microsoft.Win32.OpenFileDialog(); file.ShowDialog(); if(System.IO.Path.GetExtension(file.FileName).ToLower() is ".png" || System.IO.Path.GetExtension(file.FileName).ToLower() is ".jpg") { var BitMapImage = new BitmapImage(); BitMapImage.BeginInit(); BitMapImage.StreamSource = new MemoryStream(File.ReadAllBytes(file.FileName)); BitMapImage.EndInit(); if (_TextSelected is null) return; if (TextSelected.End.Paragraph is null) FileSystem.FileCurent.Blocks.Add(new Paragraph()); FileSystem.FileCurent.Blocks.InsertBefore(TextSelected.End.Paragraph, new BlockUIContainer(new ResizeAdorner(new Image { Source = BitMapImage }))); } }
问题原因
ResizeAdorner属于**Adorner(装饰器)**类型,它不是常规UIElement,不能直接作为BlockUIContainer的内容。Adorner的作用是附加到已存在的UIElement上,且必须通过AdornerLayer来管理,而非直接替换原控件作为容器内容。
正确实现方案
需要先将Image添加到FlowDocument中,等Image加载到可视化树后,再为其添加ResizeAdorner。具体实现代码如下:
public ICommand ImageCommand { get; set; } private bool CanImageExecute(object parameter) => true; private void OnImageExecute(object parameter) { var file = new Microsoft.Win32.OpenFileDialog(); if (file.ShowDialog() != true) return; // 处理用户取消选择文件的情况 var extension = System.IO.Path.GetExtension(file.FileName).ToLower(); if (extension is ".png" or ".jpg") { var bitmapImage = new BitmapImage(); bitmapImage.BeginInit(); bitmapImage.StreamSource = new MemoryStream(File.ReadAllBytes(file.FileName)); bitmapImage.CacheOption = BitmapCacheOption.OnLoad; // 防止图片文件被锁定 bitmapImage.EndInit(); if (_TextSelected is null) return; if (TextSelected.End.Paragraph is null) FileSystem.FileCurent.Blocks.Add(new Paragraph()); var image = new Image { Source = bitmapImage }; // 监听Loaded事件,确保控件已进入可视化树再添加装饰器 image.Loaded += (s, e) => { var adornerLayer = AdornerLayer.GetAdornerLayer(image); if (adornerLayer != null) { adornerLayer.Add(new ResizeAdorner(image)); } }; FileSystem.FileCurent.Blocks.InsertBefore(TextSelected.End.Paragraph, new BlockUIContainer(image)); } }
额外注意事项
- 添加
BitmapCacheOption.OnLoad:避免程序锁定图片文件,导致无法删除或修改文件 - 增加对话框确认判断:处理用户取消选择文件的场景
- 延迟添加Adorner:必须在Image加载完成后获取AdornerLayer,否则
GetAdornerLayer会返回null
内容的提问来源于stack exchange,提问作者Vladlen
相关产品推荐
相关产品推荐

