如何处理WPF页面中的事件

时间:2015-08-18 13:14:02

标签: c# wpf xaml

我使用C#创建不同类型的“类似向导”的应用程序。一开始我使用WinForms和一个制表符控件来引导用户通过不同的选择,但现在我正在使用WPF和页面。这样,它更清晰,更容易修改。它就像我需要它一样工作,但是一旦我正在努力解决的事情就是事件。

例如,我有以下结构(照相亭申请):

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

在这种情况下,我创建了一个MasterPage,它包含整个主题和一个可以保存内容(页面)的框架。欢迎页面在启动时加载,用户单击下一步,拍照并自动转移到预览页面。用户可以从此处重新拍摄照片或退出并显示“完成”页面。我希望这有点道理......

无论如何,我的问题是我真的不知道如何使用触发事件的对象。在这种情况下,我有一个CameraHandler对象,它有多个事件,如ImageTaken或PreviewUpdated。

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

所以我不知道该怎么做。我试图将MasterPage中的CameraHandler或外部类定义为公共变量,以便不会一直处理它,但这也不是很好。现在我没有创建CameraHandler对象的新实例,但事件每次都会被激活,因为每次用户重新加载定义事件处理程序的Photo.xaml页面时它都会添加事件...

我希望有人理解这个问题并且有一些建议。 :) 这不是关于特定情况,而是关于页面和事件的一般问题。

修改 这是“Photo.xaml”的代码:http://pastebin.com/XZBkLj4k

2 个答案:

答案 0 :(得分:1)

尝试将相机初始化移至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;
  }
}

并从Page_Unloaded event:

中的事件中删除
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_Unloaded(我没有看到xaml)

如果没有帮助,您应该在CameraHandler中创建并处理MainWindow,并将to trought属性或构造函数参数传递给页面。但相机的激活/停用会保留在照片页面中。换句话说,处理CameraHandler,因为它是单身。

答案 1 :(得分:0)

您是否考虑过使用PRISM?这可能有助于解决您的问题。

使用EventAggregator可以根据类型发布/订阅事件;例如你像这样声明事件:

public class ImageCapturedEvent : PubSubEvent<MyImageType>
{
}

订阅者可以在您定义的方法中监听这样的图像:

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

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

然后当用户拍摄图像时,您的代码可以将其发布给所有订阅者:

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

PRISM还支持MEF或Unity,因此您可以在加载时引导EventAggregator和ImageHandler的实例,并将其提供给应用程序的其余部分。

完整文档为here