我使用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
答案 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。