Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/287.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如何跨WPF页面处理事件_C#_Wpf_Xaml - Fatal编程技术网

C# 如何跨WPF页面处理事件

C# 如何跨WPF页面处理事件,c#,wpf,xaml,C#,Wpf,Xaml,我使用C#创建不同类型的“向导式”应用程序。起初,我使用WinForms和选项卡控件引导用户进行不同的选择,但现在我使用WPF和页面。这样更干净,更容易修改。它的工作原理和我所需要的一样,但我现在正在努力解决的一件事就是事件 例如,我有以下结构(照片亭应用程序): 在本例中,我创建了一个包含整个主题的母版页和一个包含内容(页面)的框架。“欢迎”页面在启动时加载,用户单击“下一步”,拍照并自动传输到预览页面。从这里,用户可以重新拍摄照片或退出并显示“完成”页面。我希望这有点道理 无论如何,我的问题

我使用C#创建不同类型的“向导式”应用程序。起初,我使用WinForms和选项卡控件引导用户进行不同的选择,但现在我使用WPF和页面。这样更干净,更容易修改。它的工作原理和我所需要的一样,但我现在正在努力解决的一件事就是事件

例如,我有以下结构(照片亭应用程序):

在本例中,我创建了一个包含整个主题的母版页和一个包含内容(页面)的框架。“欢迎”页面在启动时加载,用户单击“下一步”,拍照并自动传输到预览页面。从这里,用户可以重新拍摄照片或退出并显示“完成”页面。我希望这有点道理

无论如何,我的问题是我真的不知道如何使用触发事件的对象。在本例中,我有一个CameraHandler对象,它有多个事件,如ImageTaked或PreviewUpdated

起初,每次加载页面“Photo”时,我都定义一个新的CameraHandler实例,并在触发页面卸载时处理它。为了将图像传递到下一页,我只使用事件ImageCapture将图像保存到当前会话的用户对象。但是,如果用户继续拍摄照片,然后重新拍摄,则CameraHandler将被创建和处理太多次,从而导致应用程序崩溃。Windows事件查看器实际上说,由于驱动程序错误,它断开了摄像头的连接。这仍然是处理事件(经常创建和处理事件)的更好方法吗

所以我不知道该怎么办。我试图在母版页或外部类中将CameraHandler定义为一个公共变量,以避免一直对其进行处理,但结果也不太理想。现在,我不创建CameraHandler对象的新实例,但事件会被激发多次,因为每次用户重新加载定义了事件处理程序的Photo.xaml页面时,它都会添加事件

我希望有人能理解这个问题,并提出一些建议。:) 这不是一个具体的案例,而是一个关于页面和事件的一般性问题

编辑:
以下是“Photo.xaml”的代码:

您研究过使用PRISM吗?这可能有助于解决你的问题

使用EventAggregator将允许您基于类型发布/订阅事件;e、 g.您这样声明事件:

public class ImageCapturedEvent : PubSubEvent<MyImageType>
{
}
公共类ImageCaptureEvent:PubSubEvent
{
}
订阅者可以使用您定义的方法来侦听图像:

_eventAggregator.GetEvent<ImageCapturedEvent >().Subscribe(OnImageCaptured);

public void OnImageCaptured(MyImageType image)
{
     //process image
}
\u eventAggregator.GetEvent().Subscribe(OnImageCaptured);
已捕获公共图像(MyImageType图像)
{
//处理图像
}
然后,当用户拍摄图像时,您的代码可以将其发布到所有订阅者:

_eventAggregator.GetEvent<ImageCapturedEvent>().Publish(capturedImage);
\u eventAggregator.GetEvent().Publish(capturedImage);
PRISM还支持MEF或Unity,因此您可以在加载时引导EventAggregator和ImageHandler的实例,并使它们对应用程序的其余部分可用


完整的文档已保存。

尝试将摄像头初始化移动到第页。加载事件:

Page_Loaded(object sender, EventArgs e)
{
  if (CameraHandler != null)
  {
    CameraHandler = new SDKHandler();
    CameraHandler.LiveViewUpdated += new CameraHandler_LiveViewUpdated;
    CameraHandler.ProgressChanged += CameraHandler_ProgressChanged;
    CameraHandler.CameraHasShutdown += CameraHandler_CameraHasShutdown;
    CameraHandler.ImageSaveDirectory = Settings.TempLocation;
  }
}
并从页面中的事件中删除已卸载事件:

Page_Unloaded(object sender, EventArgs e)
{
   if (!CameraHandler.IsFilming && CameraHandler.IsLiveViewOn)
   {
      CameraHandler.StopLiveView();
   }

   //maybe you were missing this
   if (CameraHandler.CameraSessionOpen) {
      CameraHandler.CloseSession();
   }

   CameraHandler.LiveViewUpdated -= CameraHandler_LiveViewUpdated;
   CameraHandler.ProgressChanged -= CameraHandler_ProgressChanged;
   CameraHandler.CameraHasShutdown -= CameraHandler_CameraHasShutdown;
   CameraHandler.Dispose();
   CameraHandler = null;
}
确保调用了
Page\u unload
(我没有看到xaml)


如果没有帮助,您应该在
main窗口中创建和处理
CameraHandler
,并将is-trought属性或构造函数参数传递到页面。但是,相机的激活/停用保留在照片页面中。换句话说,将CameraHandler作为单例处理。

我认为应用程序崩溃是由于在创建CameraHandler类、将事件处理程序附加到这些类时发生OutOfMemoryException造成的,它们无法被垃圾收集,因为事件处理程序从未被解除跟踪。如果没有代码,任何人都很难给出答案。你可以在母版页中创建camerahandler实例,并找到从页面引用它的方法,不是吗?你会得到什么异常?根据描述,我猜他的问题与事件无关,但是对象生命周期不应该是CameraHandler=new SDKHandler();是否移动到Page_加载函数之外并放置在我的母版页或其他cs文件中?我不确定我是否对如何实际工作有正确的想法,但我认为在页面中定义的对象更经常被创建和垃圾收集,因为页面是您更经常创建和处理的元素(当您导航时)。在卸载的第_页中处理CameraHandler很可能也会导致与我今天经常创建和处理CameraHandler相同的问题?好吧,如果SDKHandler工作正常,那么您应该能够根据需要多次处理和重新创建它。但是,类中可能存在错误,并且无法正确处理。那么是的,您应该只使用SDKHandler的单个实例。还要注意,WPF有时会回收页面。因此,当您返回到以前访问过的页面时,它不会创建新实例,而是重用现有实例。
Page_Unloaded(object sender, EventArgs e)
{
   if (!CameraHandler.IsFilming && CameraHandler.IsLiveViewOn)
   {
      CameraHandler.StopLiveView();
   }

   //maybe you were missing this
   if (CameraHandler.CameraSessionOpen) {
      CameraHandler.CloseSession();
   }

   CameraHandler.LiveViewUpdated -= CameraHandler_LiveViewUpdated;
   CameraHandler.ProgressChanged -= CameraHandler_ProgressChanged;
   CameraHandler.CameraHasShutdown -= CameraHandler_CameraHasShutdown;
   CameraHandler.Dispose();
   CameraHandler = null;
}