简体   繁体   English

如何处理WPF页面上的事件

[英]How to handle events across WPF pages

I use C# for creating different types of "Wizard-like" applications. 我使用C#创建不同类型的“类向导”应用程序。 In the beginning I was using WinForms and a tab-control to guide users through different choices, but now I'm using WPF and pages. 最初,我使用WinForms和一个选项卡控件来引导用户进行不同的选择,但是现在我使用的是WPF和页面。 This way it's much cleaner and easier to modify. 这样,它更干净,更容易修改。 It works just as I need it to, but once thing I'm now struggling with are events. 它可以按我需要的方式工作,但是一旦我遇到麻烦,事情就会发生。

For example I have the following structure (a photo booth application): 例如,我具有以下结构(照相亭应用程序):

- MasterPage.xaml
|-- Welcome.xaml
|-- Photo.xaml
|-- Preview.xaml
|-- Done.xaml

In this case I create a MasterPage that holds the overall theme and a frame that can hold the content (pages). 在这种情况下,我将创建一个包含整个主题的MasterPage和一个可以容纳内容(页面)的框架。 The welcome-page is loading on startup, the user clicks next, takes a picture and is automatically transferred to the preview page. 欢迎页面在启动时加载,用户单击下一步,拍照,然后自动转移到预览页面。 From here the user can either retake the photo or quit and be presented with the "Done" page. 用户可以从此处重新拍摄照片或退出并显示“完成”页面。 I hope that somewhat makes sense... 我希望这有道理...

Anyway, my issue is that I don't really know how to use objects that fires events. 无论如何,我的问题是我真的不知道如何使用触发事件的对象。 In this case I have a CameraHandler object that has multiple events like ImageTaken or PreviewUpdated. 在这种情况下,我有一个CameraHandler对象,该对象具有多个事件,例如ImageTaken或PreviewUpdated。

At first I defined a new instance of CameraHandler each time the pages "Photo" was loaded and disposed of it when the page_unload got triggered. 最初,每次触发page_unload时,每次加载和处理“照片”页面时,我都会定义一个CameraHandler的新实例。 In order to pass the image to the next page I just used the event ImageTaken to save the image to a user object for that current session. 为了将图像传递到下一页,我只使用了ImageTaken事件将图像保存到该当前会话的用户对象。 However, if a user kept taking pictures and then retake it, the CameraHandler would be created and disposed too many times and resulting in crashing the application. 但是,如果用户继续拍照然后再拍摄,则CameraHandler将被创建和处理太多次,从而导致应用程序崩溃。 The Windows event viewer actually said that it disconnects the camera because of a driver error. Windows事件查看器实际上表示由于驱动程序错误而断开了相机的连接。 Is this still a preferable way of handling events (creating them often and disposing them)? 这仍然是处理事件(经常创建事件并对其进行处置)的首选方法吗?

So I'm not sure what to do. 所以我不确定该怎么办。 I've tried to define the CameraHandler in the MasterPage or an external class as a public variable in order to not dispose it all the time, but that didn't work out too well either. 我试图在MasterPage或外部类中将CameraHandler定义为公共变量,以便不一直对其进行处理,但这也不太可行。 Now I don't create a new instance of the CameraHandler object, but events are getting fired multiple times since it adds the events every time the user reload that Photo.xaml page where the event handlers are defined... 现在,我没有创建CameraHandler对象的新实例,但是事件被多次触发,因为每次用户重新加载定义了事件处理程序的Photo.xaml页面时,它都会添加事件...

I hope someone understands the issue and has some word of advise. 我希望有人能理解这个问题并有所建议。 :) This is not about a specific case, but more a general question about pages and events. :)这不是关于特定情况,而是关于页面和事件的一般性问题。

Edit: Here's the code for the "Photo.xaml": http://pastebin.com/XZBkLj4k 编辑:这是“ Photo.xaml”的代码: http ://pastebin.com/XZBkLj4k

Try to move camera initialization to Page.Load event: 尝试将相机初始化移动到Page.Load事件:

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;
  }
}

and detactch from events in Page_Unloaded event: 并从Page_Unloaded事件中的事件中删除:

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;
}

make sure Page_Unloaded is called (I don't see the xaml) 确保调用了Page_Unloaded (我看不到xaml)

if it doesn't help, you should create and dispose CameraHandler in MainWindow and pass is trought property or constructor parameter to the page. 如果没有帮助,则应该在MainWindow创建并CameraHandler ,然后将trought属性或构造函数参数传递给页面。 however activation/deactivation of the camera keep in Photo page. 但是,相机的激活/关闭保持在“照片”页面中。 In other words, handle CameraHandler as it was singleton. 换句话说,请处理CameraHandler,因为它是单例的。

Have you looked into using PRISM? 您是否考虑过使用PRISM? This may help solve your problems. 这可能有助于解决您的问题。

Using the EventAggregator would allow you to publish / subscribe events based on a type; 使用EventAggregator将允许您基于类型发布/订阅事件; eg you declare the event like so: 例如,您这样声明事件:

public class ImageCapturedEvent : PubSubEvent<MyImageType>
{
}

subscribers can listen for images like so in a method you've defined: 订户可以在您定义的方法中像这样收听图像:

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

public void OnImageCaptured(MyImageType image)
{
     //process image
}

then when the user takes an image, your code can publish it to all subscribers: 然后当用户拍摄图像时,您的代码可以将其发布给所有订阅者:

_eventAggregator.GetEvent<ImageCapturedEvent>().Publish(capturedImage);

PRISM also supports MEF or Unity so you can bootstrap your instances of the EventAggregator and your ImageHandler on load and make them available to the rest of the application. PRISM还支持MEF或Unity,因此您可以在加载时引导EventAggregator和ImageHandler的实例,并使它们可用于应用程序的其余部分。

Complete documentation is here . 完整的文档在这里

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM