C# 如何在单独的静态类中更新WPF image.Source的值更改
我最近从表单切换到WPF以获得一些新的专业知识。 首先,我想编写一个摄像头应用程序。 摄影机在其自己的静态类中访问(因为我只有一个摄影机,所以不需要多个实例)。 UI应该通过图像控件在实时视图中显示当前图像。camera类在无限循环中更新BitmapSource,然后我想将其用作图像控件的源 我只是不知道如何使bitmapSource的更改导致图像控件的更新。这通常是如何做到的?我阅读了有关Propertychangedevents的内容,但不知道如何在此场景中实现它们。C# 如何在单独的静态类中更新WPF image.Source的值更改,c#,wpf,data-binding,camera,C#,Wpf,Data Binding,Camera,我最近从表单切换到WPF以获得一些新的专业知识。 首先,我想编写一个摄像头应用程序。 摄影机在其自己的静态类中访问(因为我只有一个摄影机,所以不需要多个实例)。 UI应该通过图像控件在实时视图中显示当前图像。camera类在无限循环中更新BitmapSource,然后我想将其用作图像控件的源 我只是不知道如何使bitmapSource的更改导致图像控件的更新。这通常是如何做到的?我阅读了有关Propertychangedevents的内容,但不知道如何在此场景中实现它们。 在我以前的表单应用程序
在我以前的表单应用程序中,我有一个计时器,它每秒更新表单30次,并使用公共位图作为picturebox控件的源。但这是一个丑陋的方式,我想做得更好 代码如下所示: 相机类
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,通过查看
INotifyPropertyChanged
,您不会做错任何事情。如果您在stack overflow上搜索示例,这将给您一个温和的介绍
有了它,您通常会使用类似于以下内容的数据将XAML图像绑定到图像源
<Image Source="{Binding CurrentCameraImage}" />
上面的代码只是一个指示,我现在不在电脑前
为了避免使用静态类,可以将CameraClass
转换为Singleton
这有意义吗?如果数据绑定方法不是您想要的(例如,您需要了解BindingContext是什么),那么请查看如何包含
事件
s:您的camera类将定义一个事件,您的主类将订阅该事件。然后,该事件将向您的主类发出更新可用的信号,并允许您从相机更新UI上的图片。正如您所说,您希望了解WPF,通过查看INotifyPropertyChanged
,您不会做错任何事情。如果您在stack overflow上搜索示例,这将给您一个温和的介绍
有了它,您通常会使用类似于以下内容的数据将XAML图像绑定到图像源
<Image Source="{Binding CurrentCameraImage}" />
上面的代码只是一个指示,我现在不在电脑前
为了避免使用静态类,可以将CameraClass
转换为Singleton
这有意义吗?如果数据绑定方法不是您想要的(例如,您需要了解BindingContext是什么),那么请查看如何包含
事件
s:您的camera类将定义一个事件,您的主类将订阅该事件。然后,该事件将通知主类更新可用,并允许您从相机更新UI上的图片。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;
}
});
}
}
public MainWindow()
{
InitializeComponent();
var viewModel = new CameraViewModel();
viewModel.StartCamera();
DataContext = viewModel;
}
在主窗口构造函数中,您将创建视图模型的实例,并将其分配给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;
}
});
}
}
public MainWindow()
{
InitializeComponent();
var viewModel = new CameraViewModel();
viewModel.StartCamera();
DataContext = viewModel;
}
最后,XAML中有一个图像元素绑定到视图模型的CurrentCameraImage
属性:
<Image Source="{Binding CurrentCameraImage}"/>
在视图模型的改进实现中,任务可能应该以异步方法等待。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;
}
});
}
}
public MainWindow()
{
InitializeComponent();
var viewModel = new CameraViewModel();
viewModel.StartCamera();
DataContext = viewModel;
}
在主窗口构造函数中,您将创建视图模型的实例,并将其分配给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;
}
});
}
}
public MainWindow()
{
InitializeComponent();
var viewModel = new CameraViewModel();
viewModel.StartCamera();
DataContext = viewModel;
}
最后,XAML中有一个图像元素绑定到视图模型的CurrentCameraImage
属性:
<Image Source="{Binding CurrentCameraImage}"/>
在视图模型的改进实现中,任务可能应该在异步方法中等待。尝试INotifyPropertyChanged是我要做的第一件事。但是将它应用到静态类会给我一个错误,即“静态类不能实现接口”。好的,在这种情况下,也许你可以使用singleton。尝试INotifyPropertyChanged是我做的第一件事。但是将它应用到静态类会给我一个错误,说“静态类不能实现接口”。好吧,在这种情况下,也许你可以使用singleton。但这实际上不是一个关于如何使用静态类来实现这一点的答案否?不,但它显示了你应该如何真正做到这一点。在StackOverflow上,答案通常超出问题的细节,以便向提问者(以及其他人)展示问题通常是如何解决的。由于一般解决方案不起作用,因此问题对于如何使用静态类实现这一点非常具体。您的回答只是对文档的重写,并没有回答实际问题。我很感谢你的回应,但我不能正式接受,因为这并不能解决问题。在我的项目中,我现在忽略了静态类-但这只是因为我找不到任何其他方法,而不是因为我想:(但这实际上不是一个关于如何使用静态类来实现这一点的答案吗?不,但它显示了你应该如何真正做到这一点。在StackOverflow上,答案通常超出了问题的细节,以便向提问者展示(以及其他随之而来的人)问题通常是如何解决的。问题非常具体,关于如何使用静态类来解决这个问题,因为一般解决方案不起作用。您的答案只是重写