惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

博客园 - 叶小钗
D
Darknet – Hacking Tools, Hacker News & Cyber Security
S
SegmentFault 最新的问题
博客园 - 三生石上(FineUI控件)
雷峰网
雷峰网
WordPress大学
WordPress大学
有赞技术团队
有赞技术团队
博客园 - 【当耐特】
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
V
V2EX
V
Visual Studio Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园 - 聂微东
P
Proofpoint News Feed
Last Week in AI
Last Week in AI
U
Unit 42
W
WeLiveSecurity
博客园 - Franky
Recent Announcements
Recent Announcements
Hacker News - Newest:
Hacker News - Newest: "LLM"
Attack and Defense Labs
Attack and Defense Labs
月光博客
月光博客
The Cloudflare Blog
Spread Privacy
Spread Privacy
腾讯CDC
P
Privacy International News Feed
N
News and Events Feed by Topic
AWS News Blog
AWS News Blog
NISL@THU
NISL@THU
T
Troy Hunt's Blog
小众软件
小众软件
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
Webroot Blog
Webroot Blog
Y
Y Combinator Blog
量子位
P
Palo Alto Networks Blog
N
News and Events Feed by Topic
V
Vulnerabilities – Threatpost
K
Kaspersky official blog
IT之家
IT之家
T
Threat Research - Cisco Blogs
Cloudbric
Cloudbric
云风的 BLOG
云风的 BLOG
C
Check Point Blog
Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
G
Google Developers Blog
S
Secure Thoughts

博客园 - 江南白衣

花开在眼前 多收了三五斗 SQL Server 2008 Spatial Tools Visual Studio 2008 Service Pack 1 Release View to Presenter Communication Polymorphic Databinding Solutions Composite Application Guidance - What is it? AddIn Enabled Applications 带套的日子 NET Debugger Visualizers List Composite Application Guidance for WPF-June 2008 Managed Extensibility Framework (MEF) Managed Extensibility and Add-In Framework 祝我生日快乐 Why use the Entity Framework? Entity Framework FAQ Visual Studio 2008 SP1: Sync Services for ADO.Net with SQL Server 2008 Change Tracking (转) Managed Services for Windows Mobile xUnit.net 1.0.1 Realese
Unsaved Changes When CAB Application Closes: The Notification Pattern
江南白衣 · 2008-08-02 · via 博客园 - 江南白衣

Occasionally this question pops up on the CAB message boards: How do I prevent my application from closing if the user has unsaved changes?

Turns out that there’s a very simple pattern you can utilize to handle this situation. It’s called the Notification Pattern. Jeremy Miller, .Net guru, has a very good blog post on this pattern. He uses it to illustrate a standard way to handle validation on domain objects, but it’s a valuable pattern in other cases too, as I’ll show.

As Martin Fowler writes in his article, the Notification Pattern can be as simple as “a collection of strings which are error messages that the domain generates while it’s doing its work.” This is, in fact, how simple our implementation is where I work. A collection of strings, nothing more. You can use something else besides strings - a rich object with many properties and a public interface - if you like. But for this demonstration I’ll stick to strings.

The easiest way to implement this in CAB is with a Service class. All that is required is an event and a method to call to get notifications. The interface to the service basically looks like this:

public delegate void ApplicationClosingEventHandler(List<string> notifications);
public interface INotificationService
{
event ApplicationClosingEventHandler ApplicationClosing;
List<string> GetNotifications();
}

And the Service itself:


public class NotificationService : INotificationService
{
public virtual event ApplicationClosingEventHandler ApplicationClosing;
public virtual List<string> GetNotifications()
{
List<string> notifications = new List<string>();
if (ApplicationClosing != null)
{
foreach (ApplicationClosingEventHandler handler in ApplicationClosing.GetInvocationList())
{
handler.Invoke(_unsavedChangesNotifications);
}
}
return notifications ;
}
}

WorkItems, Presenters and other classes that know about the dirty state of their models can take a dependency on this Service and subscribe to the ApplicationClosing event. When the event is fired, their handler adds a notification to the list, if it needs to.


public MyPresenter : Presenter<IMyView>
{
private INotificationService _notificationService;
public MyPresenter([ServiceDependency] INotificationService notificationService)
{
_notificationService = notificationService;
_notificationService.ApplicationClosing += new ApplicationClosingEventHandler(AppClosingHandler);
}
private void AppClosingHandler(List<string> notifications)
{
if(myModelIsDirty)
notifications.Add("My object is dirty");
}
}

The next step is to hook the whole thing into the Shell.Closing event. Back in the ShellApplication class, typically in the AfterShellCreated override, you can wire up to the Shell.Closing event:

public override AfterShellCreated()
{
base.AfterShellCreated();
Shell.Closing += new CancelEventHandler(Shell_Closing);
}

In your handler, you can query the INotificationService and get any notifications. If the notification list is empty, you can safely exit the application. Otherwise, pop a MessageBox and alert them.

private void Shell_Closing(object sender, CancelEventArgs ee)
{
INotificationService notificationService = RootWorkItem.Services.Get<INotificationService>();
List<string> notifications = notificationService.GetNotifications();
if(notifications.Count > 0)
{
e.Cancel = true;
// Alert the user
}
}

That’s it. Simple, right? The nice thing about this pattern is that even with simple notifications, like strings, you can still give the user some very useful information on where unsaved changes exist. In our application, for instance, we let the user know which module and “use case” (very broad term here) contains the unsaved changes, so they can find those unsaved changes faster and make the save.

The Notification Pattern is one of the simplest, yet most useful, patterns that you’ll run into in any application, not just CAB. Now go forth and prevent your users from losing data when they close your app!