bd9935c3b731bf31fb2d9b0093002a0820f098a4
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / View / WorkflowViewStateService.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4
5 namespace System.Activities.Presentation.View
6 {
7     using System.Collections.Generic;
8     using System.Diagnostics.CodeAnalysis;
9     using System.Xaml;
10     using System.Activities.Presentation.Model;
11     using System.Runtime;
12
13     //ViewState is stored as a Dictionary<string, object> on the CFx object. 
14     //ModelItem is passed in StoreViewState to get a handle to the CFx object.
15     [Fx.Tag.XamlVisible(false)]
16     public class WorkflowViewStateService : ViewStateService
17     {
18         EditingContext context;
19
20         public override event ViewStateChangedEventHandler ViewStateChanged;
21
22         public override event ViewStateChangedEventHandler UndoableViewStateChanged;
23
24         [SuppressMessage(FxCop.Category.Security, FxCop.Rule.DoNotDeclareReadOnlyMutableReferenceTypes)]
25         public static readonly AttachableMemberIdentifier ViewStateName = new AttachableMemberIdentifier(typeof(WorkflowViewStateService), "ViewState");
26         
27         UndoEngine UndoEngine
28         {
29             get
30             {
31                 return this.context.Services.GetService<UndoEngine>();
32             }
33         }
34
35         public WorkflowViewStateService(EditingContext context)
36         {
37             this.context = context;
38         }
39
40         public static Dictionary<string, object> GetViewState(object instance)
41         {
42             if (instance == null)
43             {
44                 throw FxTrace.Exception.AsError(new ArgumentNullException("instance"));
45             }
46             Dictionary<string, object> viewState;
47             AttachablePropertyServices.TryGetProperty(instance, ViewStateName, out viewState);
48             return viewState;
49         }
50
51         public static void SetViewState(object instance, Dictionary<string, object> value)
52         {
53             if (instance == null)
54             {
55                 throw FxTrace.Exception.AsError(new ArgumentNullException("instance"));
56             }
57             AttachablePropertyServices.SetProperty(instance, ViewStateName, value);
58         }
59
60
61         public override object RetrieveViewState(ModelItem modelItem, string key)
62         {
63             if (modelItem == null)
64             {
65                 throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
66             }
67             if (key == null)
68             {
69                 throw FxTrace.Exception.AsError(new ArgumentNullException("key"));
70             }
71
72             object viewStateObj = null;
73             Dictionary<string, object> viewState = WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
74             if (viewState != null)
75             {
76                 viewState.TryGetValue(key, out viewStateObj);
77             }
78             return viewStateObj;
79         }
80
81         public override void StoreViewState(ModelItem modelItem, string key, object value)
82         {
83             if (modelItem == null)
84             {
85                 throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
86             }
87             if (key == null)
88             {
89                 throw FxTrace.Exception.AsError(new ArgumentNullException("key"));
90             }
91           
92             object oldValue = null;
93             Dictionary<string, object> viewState = WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
94             if (viewState == null)
95             {
96                 viewState = new Dictionary<string, object>();
97                 WorkflowViewStateService.SetViewState(modelItem.GetCurrentValue(), viewState);
98             }
99             viewState.TryGetValue(key, out oldValue);
100             if (value != null)
101             {
102                 viewState[key] = value;
103             }
104             else
105             {
106                 RemoveViewState(modelItem, key);
107             }
108             if (this.ViewStateChanged != null && value != oldValue)
109             {
110                 this.ViewStateChanged(this, new ViewStateChangedEventArgs(modelItem, key, value, oldValue));
111             }
112         }
113
114         public override bool RemoveViewState(ModelItem modelItem, string key)
115         {
116             if (modelItem == null)
117             {
118                 throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
119             }
120             if (key == null)
121             {
122                 throw FxTrace.Exception.AsError(new ArgumentNullException("key"));
123             }
124             bool itemRemoved = false;
125             Dictionary<string, object> viewState = WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
126             if (viewState != null && key != null && viewState.ContainsKey(key))
127             {
128                 itemRemoved = viewState.Remove(key);
129                 if (viewState.Keys.Count == 0)
130                 {
131                     AttachablePropertyServices.RemoveProperty(modelItem.GetCurrentValue(), ViewStateName);
132                 }
133             }
134             return itemRemoved;
135         }
136
137         public override Dictionary<string, object> RetrieveAllViewState(ModelItem modelItem)
138         {
139             if (modelItem == null)
140             {
141                 throw FxTrace.Exception.AsError(new ArgumentNullException("modelItem"));
142             }
143             return WorkflowViewStateService.GetViewState(modelItem.GetCurrentValue());
144         }
145     
146
147         public override void StoreViewStateWithUndo(ModelItem modelItem, string key, object value)
148         {
149             object oldValue = RetrieveViewState(modelItem, key);
150             ViewStateChange vsChange = new ViewStateChange(this)
151                                         {
152                                             Item = modelItem,
153                                             Key = key,
154                                             OldValue = oldValue,
155                                             NewValue = value,
156                                         };
157             ModelTreeManager modelTreeManager = this.context.Services.GetService<ModelTreeManager>();
158             if (modelTreeManager != null)
159             {
160                 modelTreeManager.AddToCurrentEditingScope(vsChange);
161             }
162         }
163
164
165         void RaiseUndoableViewStateChangedEvent(ModelItem modelItem, string key, object newValue, object oldValue)
166         {
167             if (this.UndoableViewStateChanged != null)
168             {
169                 this.UndoableViewStateChanged(this, new ViewStateChangedEventArgs(modelItem, key, newValue, oldValue));
170             }
171         }
172
173
174         internal class ViewStateChange : Change
175         {
176             protected WorkflowViewStateService viewStateService;
177
178             public ModelItem Item { get; set; }
179             public string Key { get; set; }
180             public object OldValue { get; set; }
181             public object NewValue { get; set; }
182
183             public ViewStateChange(WorkflowViewStateService viewStateService) 
184             {
185                 this.viewStateService = viewStateService;
186             }
187
188
189             public override string Description
190             {
191                 get { return SR.ViewStateUndoUnitDescription; }
192             }
193
194             public override bool Apply()
195             {
196                 viewStateService.StoreViewState(Item, Key, NewValue);
197                 this.viewStateService.RaiseUndoableViewStateChangedEvent(Item, Key, NewValue, OldValue);
198                 return true;
199             }
200
201             public override Change GetInverse()
202             {
203                 return new ViewStateChange(this.viewStateService)
204                     {
205                         Item = this.Item,
206                         Key = this.Key,
207                         OldValue = this.NewValue,
208                         NewValue = this.OldValue
209                     };
210             }
211         }
212
213
214     }
215
216 }