如何更新WPF图像.源代码在单独的静态类的值变化
本文关键字:单独 静态类 变化 源代码 图像 何更新 更新 WPF | 更新日期: 2023-09-27 18:13:56
我最近从Forms转到了WPF,以获得一些新的专业知识。首先,我想编写一个相机应用程序。相机在它自己的静态类中被访问(因为我只有一个相机-所以不需要多个实例)。UI应该通过图像控件在实时视图中显示当前图像。camera类在无限循环中更新BitmapSource,然后我想将其用作图像控件的源。
我只是不知道如何使bitmapSource的变化导致图像控件的更新。这通常是怎么做的?我读过propertychangeevent,但不知道如何在这种情况下实现它们。
在之前的Forms应用程序中,我有一个计时器,每秒更新表单30次,并使用公共位图作为图片框控件的源。但这是一种丑陋的方式,我想做得更好。
代码如下:相机类
static class CameraClass
{
static Camera myCam = new Camera(); //from API
public static BitmapSource CurrentCameraImage;
private static void GetCameraImages()
{
while(true)
{
myCam.GetImage(out CurrentCameraImage, 1000); //from API
}
}
public static void StartCamera()
{
myCam.StartAcquisition(); //from API
Task.Run(() => { GetCameraImages(); });
}
}
标准WPF类
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
CameraClass.StartCamera();
//this should now cause the image control to update
//everytime the bitmapsource is changed
}
}
WPF应用程序通常实现MVVM模式,其中视图元素绑定到视图模型中的属性。在最简单的情况下,只有一个视图模型类的实例,它被分配给应用程序的主窗口的DataContext
属性。
你的视图模型类看起来像这样:
class CameraViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private Camera camera = new Camera();
private BitmapSource currentCameraImage;
public BitmapSource CurrentCameraImage
{
get { return currentCameraImage; }
set
{
currentCameraImage = value;
PropertyChanged?.Invoke(
this, new PropertyChangedEventArgs("CurrentCameraImage"));
}
}
public async Task StartCamera()
{
await Task.Run(async () =>
{
while (true)
{
BitmapSource bitmap;
camera.GetImage(out bitmap, 1000); // from API
bitmap.Freeze(); // make bitmap cross-thread accessible
CurrentCameraImage = bitmap;
}
});
}
}
在MainWindow构造器中,您将创建视图模型的实例,并将其分配给DataContext
属性,如下所示:
public MainWindow()
{
InitializeComponent();
var viewModel = new CameraViewModel();
viewModel.StartCamera();
DataContext = viewModel;
}
最后,在XAML中将有一个Image元素绑定到视图模型的CurrentCameraImage
属性:
<Image Source="{Binding CurrentCameraImage}"/>
在视图模型的改进实现中,应该在异步方法中等待Task。
正如您所说,您想了解WPF,通过查看INotifyPropertyChanged
,您不会做任何错误的事情。如果你在这里搜索样本,甚至在堆栈溢出,这将给你一个温和的介绍。
,你通常会用类似于
的东西将XAML图像数据绑定到图像源<Image Source="{Binding CurrentCameraImage}" />
上面的代码只是一个指示,我现在不在电脑前。
为了避免静态类,你可以把CameraClass
变成Singleton
。
明白了吗?如果数据绑定方法不是你想要的(例如,你需要学习什么是BindingContext),那么看看如何包含event
s:你的相机类将定义一个事件,你的主类将订阅它。然后,该事件将向您的主类发出更新可用的信号,并允许您从相机更新UI上的图片。