Mercurial > silverbladetech
comparison Chronosv2/source/Presentation/ViewModel/WindowViewModel.cs @ 10:443821e55f06
Initial cleaned up add from Codeplex files
author | stevenh7776 stevenhollidge@hotmail.com |
---|---|
date | Tue, 21 Feb 2012 17:25:44 +0700 |
parents | |
children | 09d18d6e5f40 |
comparison
equal
deleted
inserted
replaced
9:904a9faadf8b | 10:443821e55f06 |
---|---|
1 /* | |
2 The MIT License | |
3 | |
4 Copyright (c) 2009-2010. Carlos Guzmán Álvarez. http://chronoswpf.codeplex.com/ | |
5 | |
6 Permission is hereby granted, free of charge, to any person obtaining a copy | |
7 of this software and associated documentation files (the "Software"), to deal | |
8 in the Software without restriction, including without limitation the rights | |
9 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |
10 copies of the Software, and to permit persons to whom the Software is | |
11 furnished to do so, subject to the following conditions: | |
12 | |
13 The above copyright notice and this permission notice shall be included in | |
14 all copies or substantial portions of the Software. | |
15 | |
16 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |
17 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |
18 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |
19 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |
20 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |
21 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |
22 THE SOFTWARE. | |
23 */ | |
24 | |
25 using System; | |
26 using System.ComponentModel; | |
27 using System.Threading; | |
28 using System.Threading.Tasks; | |
29 using Chronos.Presentation.Core.ViewModel; | |
30 using Chronos.Presentation.Core.Windows; | |
31 using NLog; | |
32 using nRoute.Components; | |
33 | |
34 namespace Chronos.Presentation.ViewModel | |
35 { | |
36 public abstract class WindowViewModel<TEntity> | |
37 : NavigationViewModel, IWindowViewModel where TEntity: class, new() | |
38 { | |
39 #region · Logger · | |
40 | |
41 private static Logger Logger = LogManager.GetCurrentClassLogger(); | |
42 | |
43 #endregion | |
44 | |
45 #region · Inner Types · | |
46 | |
47 [Serializable] | |
48 protected enum InquiryActionResultType | |
49 { | |
50 DataFetched, | |
51 RequestedNew, | |
52 DataNotFound | |
53 } | |
54 | |
55 protected sealed class InquiryActionResult<TResult> | |
56 where TResult : class | |
57 { | |
58 #region · Properties · | |
59 | |
60 public TResult Data | |
61 { | |
62 get; | |
63 set; | |
64 } | |
65 | |
66 public InquiryActionResultType Result | |
67 { | |
68 get; | |
69 set; | |
70 } | |
71 | |
72 #endregion | |
73 | |
74 #region · Constructors · | |
75 | |
76 public InquiryActionResult() | |
77 { | |
78 } | |
79 | |
80 #endregion | |
81 } | |
82 | |
83 #endregion | |
84 | |
85 #region · PropertyChangedEventArgs Cached Instances · | |
86 | |
87 private static readonly PropertyChangedEventArgs ViewModeChangedArgs = CreateArgs<WindowViewModel<TEntity>>(x => x.ViewMode); | |
88 private static readonly PropertyChangedEventArgs StatusMessageChangedArgs = CreateArgs<WindowViewModel<TEntity>>(x => x.StatusMessage); | |
89 private static readonly PropertyChangedEventArgs NotificationMessageChangedArgs = CreateArgs<WindowViewModel<TEntity>>(x => x.NotificationMessage); | |
90 | |
91 #endregion | |
92 | |
93 #region · Events · | |
94 | |
95 /// <summary> | |
96 /// Occurs when view mode is changed. | |
97 /// </summary> | |
98 public event EventHandler ViewModeChanged; | |
99 | |
100 #endregion | |
101 | |
102 #region · Fields · | |
103 | |
104 private TEntity originalEntity; | |
105 private string statusMessage; | |
106 private string notificationMessage; | |
107 private TEntity entity; | |
108 private ViewModeType viewMode; | |
109 private PropertyStateCollection<TEntity> propertyStates; | |
110 | |
111 #region · Commands · | |
112 | |
113 private ActionCommand inquiryCommand; | |
114 | |
115 #endregion | |
116 | |
117 #endregion | |
118 | |
119 #region · Properties · | |
120 | |
121 /// <summary> | |
122 /// Gets the property state collection | |
123 /// </summary> | |
124 public PropertyStateCollection<TEntity> PropertyStates | |
125 { | |
126 get | |
127 { | |
128 if (this.propertyStates == null) | |
129 { | |
130 this.propertyStates = new PropertyStateCollection<TEntity>(); | |
131 } | |
132 | |
133 return this.propertyStates; | |
134 } | |
135 } | |
136 | |
137 /// <summary> | |
138 /// Gets or sets the state of the smart part. | |
139 /// </summary> | |
140 /// <value>The state of the smart part.</value> | |
141 public ViewModeType ViewMode | |
142 { | |
143 get { return this.viewMode; } | |
144 set | |
145 { | |
146 if (this.viewMode != value) | |
147 { | |
148 this.viewMode = value; | |
149 try | |
150 { | |
151 this.OnViewModeChanged(); | |
152 } | |
153 catch | |
154 { | |
155 #warning TODO: This is done to prevent DataGrid erroros when discarding changes on new records | |
156 } | |
157 } | |
158 } | |
159 } | |
160 | |
161 /// <summary> | |
162 /// Gets the inquiry data command | |
163 /// </summary> | |
164 public ActionCommand InquiryCommand | |
165 { | |
166 get | |
167 { | |
168 if (this.inquiryCommand == null) | |
169 { | |
170 this.inquiryCommand = new ActionCommand | |
171 ( | |
172 () => OnInquiryData(), | |
173 () => CanInquiryData() | |
174 ); | |
175 } | |
176 | |
177 return this.inquiryCommand; | |
178 } | |
179 } | |
180 | |
181 /// <summary> | |
182 /// Gets or sets the status message text | |
183 /// </summary> | |
184 public string StatusMessage | |
185 { | |
186 get { return this.statusMessage; } | |
187 set | |
188 { | |
189 if (this.statusMessage != value) | |
190 { | |
191 this.statusMessage = value; | |
192 this.NotifyPropertyChanged(StatusMessageChangedArgs); | |
193 } | |
194 } | |
195 } | |
196 | |
197 /// <summary> | |
198 /// Gets or sets the notification message text | |
199 /// </summary> | |
200 public string NotificationMessage | |
201 { | |
202 get { return this.notificationMessage; } | |
203 set | |
204 { | |
205 if (this.notificationMessage != value) | |
206 { | |
207 this.notificationMessage = value; | |
208 this.NotifyPropertyChanged(NotificationMessageChangedArgs); | |
209 } | |
210 } | |
211 } | |
212 | |
213 #endregion | |
214 | |
215 #region · Protected Properties · | |
216 | |
217 /// <summary> | |
218 /// Gets or sets the data model. | |
219 /// </summary> | |
220 /// <value>The data model.</value> | |
221 protected TEntity Entity | |
222 { | |
223 get { return this.entity; } | |
224 private set | |
225 { | |
226 if (!Object.ReferenceEquals(this.entity, value)) | |
227 { | |
228 this.entity = value; | |
229 } | |
230 } | |
231 } | |
232 | |
233 protected TEntity OriginalEntity | |
234 { | |
235 get { return this.originalEntity; } | |
236 set { this.originalEntity = value; } | |
237 } | |
238 | |
239 #endregion | |
240 | |
241 #region · Constructors · | |
242 | |
243 protected WindowViewModel() | |
244 : base() | |
245 { | |
246 this.InitializePropertyStates(); | |
247 | |
248 this.Entity = new TEntity(); | |
249 this.ViewMode = ViewModeType.ViewOnly; | |
250 } | |
251 | |
252 #endregion | |
253 | |
254 #region · Command Actions · | |
255 | |
256 #region · Inquiry · | |
257 | |
258 protected virtual bool CanInquiryData() | |
259 { | |
260 return (this.ViewMode == ViewModeType.ViewOnly); | |
261 } | |
262 | |
263 protected void OnInquiryData() | |
264 { | |
265 InquiryActionResult<TEntity> result = new InquiryActionResult<TEntity> | |
266 { | |
267 Result = InquiryActionResultType.DataNotFound | |
268 }; | |
269 | |
270 this.ViewMode = ViewModeType.Busy; | |
271 this.StatusMessage = "Obteniendo datos, espere por favor ..."; | |
272 | |
273 Task task = Task.Factory.StartNew | |
274 ( | |
275 (o) => | |
276 { | |
277 Logger.Debug("Obteniendo datos '{0}'", this.Entity.ToString()); | |
278 | |
279 this.OnInquiryAction(result); | |
280 }, result | |
281 ); | |
282 | |
283 task.ContinueWith | |
284 ( | |
285 (t) => | |
286 { | |
287 Logger.Debug("Error al obtener datos '{0}'", t.Exception.InnerException.ToString()); | |
288 | |
289 this.OnInquiryActionFailed(); | |
290 | |
291 Exception exception = null; | |
292 this.OriginalEntity = null; | |
293 | |
294 if (t.Exception.InnerException != null) | |
295 { | |
296 exception = t.Exception.InnerException; | |
297 } | |
298 else | |
299 { | |
300 exception = t.Exception; | |
301 } | |
302 | |
303 this.NotificationMessage = exception.Message; | |
304 }, | |
305 CancellationToken.None, | |
306 TaskContinuationOptions.OnlyOnFaulted | TaskContinuationOptions.AttachedToParent, | |
307 TaskScheduler.FromCurrentSynchronizationContext() | |
308 ); | |
309 | |
310 task.ContinueWith | |
311 ( | |
312 _ => | |
313 { | |
314 Logger.Debug("Datos obtenidos correctamente '{0}'", this.Entity.ToString()); | |
315 | |
316 this.StatusMessage = null; | |
317 this.OnInquiryActionComplete(result); | |
318 }, | |
319 CancellationToken.None, | |
320 TaskContinuationOptions.OnlyOnRanToCompletion | TaskContinuationOptions.AttachedToParent, | |
321 TaskScheduler.FromCurrentSynchronizationContext() | |
322 ); | |
323 } | |
324 | |
325 protected abstract void OnInquiryAction(InquiryActionResult<TEntity> result); | |
326 | |
327 protected virtual void OnInquiryActionComplete(InquiryActionResult<TEntity> result) | |
328 { | |
329 switch (result.Result) | |
330 { | |
331 case InquiryActionResultType.DataNotFound: | |
332 this.OriginalEntity = null; | |
333 | |
334 this.ResetDataModel(); | |
335 | |
336 this.ViewMode = ViewModeType.ViewOnly; | |
337 break; | |
338 | |
339 case InquiryActionResultType.RequestedNew: | |
340 throw new InvalidOperationException("Requested New is not valid on this type of ViewModel"); | |
341 | |
342 case InquiryActionResultType.DataFetched: | |
343 this.ResetDataModel(result.Data); | |
344 | |
345 this.OriginalEntity = this.entity; | |
346 this.ViewMode = ViewModeType.ViewOnly; | |
347 break; | |
348 } | |
349 } | |
350 | |
351 protected virtual void OnInquiryActionFailed() | |
352 { | |
353 this.ViewMode = ViewModeType.ViewOnly; | |
354 } | |
355 | |
356 #endregion | |
357 | |
358 #endregion | |
359 | |
360 #region · Overriden Methods · | |
361 | |
362 /// <summary> | |
363 /// Called when the related view is being closed. | |
364 /// </summary> | |
365 public override void Close() | |
366 { | |
367 Logger.Debug("Cerrar ventana '{0}'", this.GetType()); | |
368 | |
369 if (this.originalEntity != null) | |
370 { | |
371 this.originalEntity = null; | |
372 } | |
373 if (this.entity != null) | |
374 { | |
375 this.entity = null; | |
376 } | |
377 if (this.propertyStates != null) | |
378 { | |
379 this.propertyStates.Clear(); | |
380 this.propertyStates = null; | |
381 } | |
382 | |
383 this.inquiryCommand = null; | |
384 this.statusMessage = null; | |
385 this.notificationMessage = null; | |
386 | |
387 base.Close(); | |
388 } | |
389 | |
390 #endregion | |
391 | |
392 #region · DataModel Reset Methods · | |
393 | |
394 protected void ResetDataModel() | |
395 { | |
396 Logger.Debug("Resetar model '{0}'", this.GetType()); | |
397 this.ResetDataModel(new TEntity()); | |
398 Logger.Debug("Model reseteado '{0}'", this.GetType()); | |
399 } | |
400 | |
401 protected virtual void ResetDataModel(TEntity model) | |
402 { | |
403 this.OnResetingDataModel(this.Entity, model); | |
404 | |
405 this.OriginalEntity = null; | |
406 this.Entity = model; | |
407 | |
408 this.OnResetedDataModel(model); | |
409 } | |
410 | |
411 protected virtual void OnResetingDataModel(TEntity oldModel, TEntity newModel) | |
412 { | |
413 } | |
414 | |
415 protected virtual void OnResetedDataModel(TEntity newModel) | |
416 { | |
417 this.NotifyAllPropertiesChanged(); | |
418 } | |
419 | |
420 #endregion | |
421 | |
422 #region · Protected Methods · | |
423 | |
424 protected virtual void InitializePropertyStates() | |
425 { | |
426 } | |
427 | |
428 protected virtual void OnViewModeChanged() | |
429 { | |
430 if (this.ViewModeChanged != null) | |
431 { | |
432 this.ViewModeChanged(this, new EventArgs()); | |
433 } | |
434 | |
435 this.NotifyPropertyChanged(ViewModeChangedArgs); | |
436 } | |
437 | |
438 protected virtual void UpdateAllowedUserActions() | |
439 { | |
440 this.Invoke | |
441 ( | |
442 () => | |
443 { | |
444 this.InquiryCommand.RequeryCanExecute(); | |
445 } | |
446 ); | |
447 } | |
448 | |
449 protected override void NotifyPropertyChanged(PropertyChangedEventArgs args) | |
450 { | |
451 if (args != StatusMessageChangedArgs) | |
452 { | |
453 this.StatusMessage = null; | |
454 } | |
455 if (args != NotificationMessageChangedArgs) | |
456 { | |
457 this.NotificationMessage = null; | |
458 } | |
459 | |
460 this.UpdateAllowedUserActions(); | |
461 base.NotifyPropertyChanged(args); | |
462 } | |
463 | |
464 #endregion | |
465 } | |
466 } |