AvaloniaUI MVVM中跨窗口点击按钮更新主视图图片源问题
问题场景
使用MVVM Community Toolkit开发Avalonia UI应用,支持两种图片获取方式:从文件系统加载图片、通过FlashCap库捕获摄像头图像。主视图MainView中的SKImageView控件绑定到MainViewModel的CurrentImage11属性。点击主视图按钮会打开ImageCaptureWindow,该窗口可选择摄像头设备并将捕获的图片存储为SKBitmap;捕获完成后,将ImageCaptureWindowViewModel的Image属性赋值给MainViewModel的CurrentImage11,但主视图的SKImageView并未更新显示捕获的图片。经排查,SKBitmap已正确存储,但视图未触发更新。
问题核心原因
ImageCaptureWindowViewModel的构造函数中新建了MainViewModel实例,而非引用主视图绑定的原有MainViewModel实例,导致赋值操作作用在全新的ViewModel对象上,并未影响到主视图实际绑定的那个实例,因此视图不会感知到属性变化。
解决方案
1. 传递现有MainViewModel实例到ImageCaptureWindowViewModel
打开ImageCaptureWindow时,将当前主视图绑定的MainViewModel实例作为参数传入ImageCaptureWindowViewModel的构造函数,避免新建实例:
// MainViewModel中打开捕获窗口的方法 private void OpenImageCaptureWindow() { // 传入当前MainViewModel实例 var captureViewModel = new ImageCaptureWindowViewModel(this); var captureWindow = new ImageCaptureWindow { DataContext = captureViewModel }; captureWindow.ShowDialog(this); }
2. 修改ImageCaptureWindowViewModel接收并持有主ViewModel实例
在ImageCaptureWindowViewModel中保存传入的MainViewModel引用,捕获完成后直接对该引用的属性赋值:
public class ImageCaptureWindowViewModel : ObservableObject { private readonly MainViewModel _mainViewModel; // 构造函数接收主ViewModel实例 public ImageCaptureWindowViewModel(MainViewModel mainViewModel) { _mainViewModel = mainViewModel; } // 捕获完成后的赋值逻辑 private void OnImageCaptured(SKBitmap capturedBitmap) { // 直接操作主ViewModel的属性 _mainViewModel.CurrentImage11 = capturedBitmap; } }
3. 确保CurrentImage11属性具备属性变更通知
使用MVVM Community Toolkit的[ObservableProperty]特性标记CurrentImage11的私有字段,让Toolkit自动生成带有PropertyChanged事件触发逻辑的公开属性:
public partial class MainViewModel : ObservableObject { [ObservableProperty] private SKBitmap _currentImage11; }
内容的提问来源于stack exchange,提问作者ManuelKetisch

