C# 如何在单独的静态类中更新WPF image.Source的值更改

C# 如何在单独的静态类中更新WPF image.Source的值更改,c#,wpf,data-binding,camera,C#,Wpf,Data Binding,Camera,我最近从表单切换到WPF以获得一些新的专业知识。 首先,我想编写一个摄像头应用程序。 摄影机在其自己的静态类中访问(因为我只有一个摄影机,所以不需要多个实例)。 UI应该通过图像控件在实时视图中显示当前图像。camera类在无限循环中更新BitmapSource,然后我想将其用作图像控件的源 我只是不知道如何使bitmapSource的更改导致图像控件的更新。这通常是如何做到的?我阅读了有关Propertychangedevents的内容,但不知道如何在此场景中实现它们。 在我以前的表单应用程序

我最近从表单切换到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上,答案通常超出了问题的细节,以便向提问者展示(以及其他随之而来的人)问题通常是如何解决的。问题非常具体,关于如何使用静态类来解决这个问题,因为一般解决方案不起作用。您的答案只是重写