Updates referencesource to .NET 4.7
[mono-project.git] / mcs / class / referencesource / System.Workflow.ComponentModel / AuthoringOM / Design / Dialogs / ThemeConfigurationDialog.cs
blobad60d2bfc19a7841af553fa04281b4897c290d46
1 using System;
2 using System.IO;
3 using System.Drawing;
4 using System.Reflection;
5 using System.Collections;
6 using System.Diagnostics;
7 using System.Globalization;
8 using System.CodeDom.Compiler;
9 using System.Windows.Forms;
10 using System.ComponentModel;
11 using System.Drawing.Design;
12 using System.Drawing.Drawing2D;
13 using System.Collections.Generic;
14 using System.Windows.Forms.Design;
15 using System.ComponentModel.Design;
16 using System.ComponentModel.Design.Serialization;
17 using Microsoft.Win32;
18 using System.Workflow.ComponentModel.Compiler;
20 namespace System.Workflow.ComponentModel.Design
22 /// <summary>
23 /// Summary description for ThemeConfigurationDialog.
24 /// </summary>
25 [Obsolete("The System.Workflow.* types are deprecated. Instead, please use the new types from System.Activities.*")]
26 public sealed class ThemeConfigurationDialog : System.Windows.Forms.Form
28 #region Microsoft Generated Members
29 private System.Windows.Forms.Button button3;
30 private System.Windows.Forms.TreeView designerTreeView;
31 private System.Windows.Forms.Label themeNameLabel;
32 private System.Windows.Forms.Label themeLocationLabel;
33 private System.Windows.Forms.TextBox themeNameTextBox;
34 private System.Windows.Forms.Panel themePanel;
35 private System.Windows.Forms.Panel themeConfigPanel;
36 private System.Windows.Forms.Panel dummyPreviewPanel;
37 private System.Windows.Forms.TextBox themeLocationTextBox;
38 private System.Windows.Forms.Label previewLabel;
39 private System.Windows.Forms.Label selectDesignerLabel;
40 private System.Windows.Forms.PropertyGrid propertiesGrid;
41 private System.Windows.Forms.Button themeLocationButton;
42 private System.Windows.Forms.Button okButton;
43 private System.Windows.Forms.Button cancelButton;
44 private System.Windows.Forms.Button previewButton;
46 private System.ComponentModel.IContainer components = null;
47 #endregion
49 #region Member Variables
50 private IServiceProvider serviceProvider;
51 private bool previewShown = false;
52 private WorkflowTheme bufferedTheme;
53 private DesignerPreview designerPreview;
54 private Splitter splitter;
55 private TableLayoutPanel okCancelTableLayoutPanel;
56 private TableLayoutPanel nameLocationTableLayoutPanel;
57 private bool themeDirty = false;
58 #endregion
60 #region Constructor/Destructor
61 public ThemeConfigurationDialog(IServiceProvider serviceProvider)
62 : this(serviceProvider, null)
66 public ThemeConfigurationDialog(IServiceProvider serviceProvider, WorkflowTheme theme)
68 if (serviceProvider == null)
69 throw new ArgumentNullException("serviceProvider");
71 this.serviceProvider = serviceProvider;
73 if (theme == null)
75 this.bufferedTheme = new WorkflowTheme();
76 this.themeDirty = true;
78 else
80 this.bufferedTheme = theme;
81 this.themeDirty = false;
84 this.bufferedTheme.ReadOnly = false;
86 InitializeComponent();
87 this.themeLocationButton.AutoSize = true;
89 //Set dialog fonts
90 Font = StandardFont;
91 SystemEvents.UserPreferenceChanged += new UserPreferenceChangedEventHandler(OnOperatingSystemSettingsChanged);
94 /// <summary>
95 /// Clean up any resources being used.
96 /// </summary>
97 protected override void Dispose(bool disposing)
99 if (disposing)
101 if (components != null)
102 components.Dispose();
104 SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(OnOperatingSystemSettingsChanged);
106 if (this.designerPreview != null)
108 this.designerPreview.Dispose();
109 this.designerPreview = null;
112 if (this.bufferedTheme != null)
114 ((IDisposable)this.bufferedTheme).Dispose();
115 this.bufferedTheme = null;
118 base.Dispose(disposing);
120 #endregion
122 #region Windows Form Designer generated code
123 /// <summary>
124 /// Required method for Designer support - do not modify
125 /// the contents of this method with the code editor.
126 /// </summary>
127 private void InitializeComponent()
129 System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ThemeConfigurationDialog));
130 this.designerTreeView = new System.Windows.Forms.TreeView();
131 this.themeNameLabel = new System.Windows.Forms.Label();
132 this.themeLocationLabel = new System.Windows.Forms.Label();
133 this.themeNameTextBox = new System.Windows.Forms.TextBox();
134 this.nameLocationTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
135 this.themeLocationButton = new System.Windows.Forms.Button();
136 this.themeLocationTextBox = new System.Windows.Forms.TextBox();
137 this.button3 = new System.Windows.Forms.Button();
138 this.okButton = new System.Windows.Forms.Button();
139 this.cancelButton = new System.Windows.Forms.Button();
140 this.themePanel = new System.Windows.Forms.Panel();
141 this.themeConfigPanel = new System.Windows.Forms.Panel();
142 this.propertiesGrid = new System.Windows.Forms.PropertyGrid();
143 this.previewLabel = new System.Windows.Forms.Label();
144 this.selectDesignerLabel = new System.Windows.Forms.Label();
145 this.dummyPreviewPanel = new System.Windows.Forms.Panel();
146 this.previewButton = new System.Windows.Forms.Button();
147 this.okCancelTableLayoutPanel = new System.Windows.Forms.TableLayoutPanel();
148 this.nameLocationTableLayoutPanel.SuspendLayout();
149 this.themePanel.SuspendLayout();
150 this.themeConfigPanel.SuspendLayout();
151 this.okCancelTableLayoutPanel.SuspendLayout();
152 this.SuspendLayout();
154 // designerTreeView
156 resources.ApplyResources(this.designerTreeView, "designerTreeView");
157 this.designerTreeView.Name = "designerTreeView";
159 // themeNameLabel
161 resources.ApplyResources(this.themeNameLabel, "themeNameLabel");
162 this.themeNameLabel.Margin = new System.Windows.Forms.Padding(0, 0, 3, 3);
163 this.themeNameLabel.Name = "themeNameLabel";
165 // themeLocationLabel
167 resources.ApplyResources(this.themeLocationLabel, "themeLocationLabel");
168 this.themeLocationLabel.Margin = new System.Windows.Forms.Padding(0, 3, 3, 0);
169 this.themeLocationLabel.Name = "themeLocationLabel";
171 // themeNameTextBox
173 resources.ApplyResources(this.themeNameTextBox, "themeNameTextBox");
174 this.nameLocationTableLayoutPanel.SetColumnSpan(this.themeNameTextBox, 2);
175 this.themeNameTextBox.Margin = new System.Windows.Forms.Padding(3, 0, 0, 3);
176 this.themeNameTextBox.Name = "themeNameTextBox";
178 // nameLocationTableLayoutPanel
180 resources.ApplyResources(this.nameLocationTableLayoutPanel, "nameLocationTableLayoutPanel");
181 this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
182 this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 100F));
183 this.nameLocationTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle());
184 this.nameLocationTableLayoutPanel.Controls.Add(this.themeNameLabel, 0, 0);
185 this.nameLocationTableLayoutPanel.Controls.Add(this.themeNameTextBox, 1, 0);
186 this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationButton, 2, 1);
187 this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationLabel, 0, 1);
188 this.nameLocationTableLayoutPanel.Controls.Add(this.themeLocationTextBox, 1, 1);
189 this.nameLocationTableLayoutPanel.Name = "nameLocationTableLayoutPanel";
190 this.nameLocationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
191 this.nameLocationTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 50F));
193 // themeLocationButton
195 resources.ApplyResources(this.themeLocationButton, "themeLocationButton");
196 this.themeLocationButton.Margin = new System.Windows.Forms.Padding(3, 3, 0, 0);
197 this.themeLocationButton.Name = "themeLocationButton";
199 // themeLocationTextBox
201 resources.ApplyResources(this.themeLocationTextBox, "themeLocationTextBox");
202 this.themeLocationTextBox.Margin = new System.Windows.Forms.Padding(3, 3, 3, 0);
203 this.themeLocationTextBox.Name = "themeLocationTextBox";
205 // button3
207 resources.ApplyResources(this.button3, "button3");
208 this.button3.Name = "button3";
210 // okButton
212 resources.ApplyResources(this.okButton, "okButton");
213 this.okButton.DialogResult = System.Windows.Forms.DialogResult.OK;
214 this.okButton.Margin = new System.Windows.Forms.Padding(0, 0, 3, 0);
215 this.okButton.Name = "okButton";
217 // cancelButton
219 resources.ApplyResources(this.cancelButton, "cancelButton");
220 this.cancelButton.DialogResult = System.Windows.Forms.DialogResult.Cancel;
221 this.cancelButton.Margin = new System.Windows.Forms.Padding(3, 0, 3, 0);
222 this.cancelButton.Name = "cancelButton";
224 // themePanel
226 this.themePanel.Controls.Add(this.themeConfigPanel);
227 this.themePanel.Controls.Add(this.previewLabel);
228 this.themePanel.Controls.Add(this.selectDesignerLabel);
229 this.themePanel.Controls.Add(this.dummyPreviewPanel);
230 resources.ApplyResources(this.themePanel, "themePanel");
231 this.themePanel.Margin = new System.Windows.Forms.Padding(4);
232 this.themePanel.Name = "themePanel";
234 // themeConfigPanel
236 this.themeConfigPanel.Controls.Add(this.designerTreeView);
237 this.themeConfigPanel.Controls.Add(this.propertiesGrid);
238 resources.ApplyResources(this.themeConfigPanel, "themeConfigPanel");
239 this.themeConfigPanel.Name = "themeConfigPanel";
241 // propertiesGrid
243 this.propertiesGrid.CommandsVisibleIfAvailable = true;
244 resources.ApplyResources(this.propertiesGrid, "propertiesGrid");
245 this.propertiesGrid.Name = "propertiesGrid";
246 this.propertiesGrid.ToolbarVisible = false;
248 // previewLabel
250 resources.ApplyResources(this.previewLabel, "previewLabel");
251 this.previewLabel.Name = "previewLabel";
253 // selectDesignerLabel
255 resources.ApplyResources(this.selectDesignerLabel, "selectDesignerLabel");
256 this.selectDesignerLabel.Name = "selectDesignerLabel";
258 // dummyPreviewPanel
260 resources.ApplyResources(this.dummyPreviewPanel, "dummyPreviewPanel");
261 this.dummyPreviewPanel.Name = "dummyPreviewPanel";
263 // previewButton
265 resources.ApplyResources(this.previewButton, "previewButton");
266 this.previewButton.Margin = new System.Windows.Forms.Padding(3, 0, 0, 0);
267 this.previewButton.Name = "previewButton";
269 // okCancelTableLayoutPanel
271 resources.ApplyResources(this.okCancelTableLayoutPanel, "okCancelTableLayoutPanel");
272 this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
273 this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
274 this.okCancelTableLayoutPanel.ColumnStyles.Add(new System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent, 33F));
275 this.okCancelTableLayoutPanel.Controls.Add(this.okButton, 0, 0);
276 this.okCancelTableLayoutPanel.Controls.Add(this.cancelButton, 1, 0);
277 this.okCancelTableLayoutPanel.Controls.Add(this.previewButton, 2, 0);
278 this.okCancelTableLayoutPanel.Name = "okCancelTableLayoutPanel";
279 this.okCancelTableLayoutPanel.RowStyles.Add(new System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Percent, 100F));
281 // ThemeConfigurationDialog
283 this.AcceptButton = this.okButton;
284 this.CancelButton = this.cancelButton;
285 resources.ApplyResources(this, "$this");
286 this.Controls.Add(this.nameLocationTableLayoutPanel);
287 this.Controls.Add(this.okCancelTableLayoutPanel);
288 this.Controls.Add(this.themePanel);
289 this.Controls.Add(this.button3);
290 this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
291 this.MaximizeBox = false;
292 this.MinimizeBox = false;
293 this.Name = "ThemeConfigurationDialog";
294 this.ShowInTaskbar = false;
295 this.HelpButton = true;
296 this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
297 this.nameLocationTableLayoutPanel.ResumeLayout(false);
298 this.nameLocationTableLayoutPanel.PerformLayout();
299 this.themePanel.ResumeLayout(false);
300 this.themeConfigPanel.ResumeLayout(false);
301 this.okCancelTableLayoutPanel.ResumeLayout(false);
302 this.okCancelTableLayoutPanel.PerformLayout();
303 this.ResumeLayout(false);
304 this.PerformLayout();
307 #endregion
309 #region Properties and Methods
310 public WorkflowTheme ComposedTheme
314 return this.bufferedTheme;
318 protected override void OnLoad(EventArgs e)
320 base.OnLoad(e);
324 Cursor.Current = Cursors.WaitCursor;
325 InitializeControls();
327 finally
329 Cursor.Current = Cursors.Default;
333 protected override void OnClosing(CancelEventArgs e)
335 base.OnClosing(e);
337 this.bufferedTheme.ReadOnly = true;
339 #endregion
341 #region Helper Functions
342 private Font StandardFont
346 Font font = SystemInformation.MenuFont;
347 if (this.serviceProvider != null)
349 IUIService uisvc = (IUIService)this.serviceProvider.GetService(typeof(IUIService));
350 if (uisvc != null)
351 font = (Font)uisvc.Styles["DialogFont"];
353 return font;
357 private void InitializeControls()
359 HelpButtonClicked += new CancelEventHandler(OnHelpClicked);
361 this.themeNameTextBox.Text = this.bufferedTheme.Name;
362 this.themeLocationTextBox.Text = this.bufferedTheme.FilePath;
364 this.propertiesGrid.PropertySort = PropertySort.Categorized;
366 //Make sure that size and location are changed after adding the control to the parent
367 //this will autoscale the control correctly
368 this.designerPreview = new DesignerPreview(this);
369 this.dummyPreviewPanel.Parent.Controls.Add(this.designerPreview);
370 this.designerPreview.TabStop = false;
371 this.designerPreview.Location = this.dummyPreviewPanel.Location;
372 this.designerPreview.Size = this.dummyPreviewPanel.Size;
373 this.dummyPreviewPanel.Visible = false;
374 this.designerPreview.Parent.Controls.Remove(this.dummyPreviewPanel);
376 this.designerTreeView.ShowLines = false;
377 this.designerTreeView.ShowPlusMinus = false;
378 this.designerTreeView.ShowRootLines = false;
379 this.designerTreeView.ShowNodeToolTips = true;
380 this.designerTreeView.HideSelection = false;
381 this.designerTreeView.ItemHeight = Math.Max(this.designerTreeView.ItemHeight, 18);
382 ThemeConfigHelpers.PopulateActivities(this.serviceProvider, this.designerTreeView);
384 this.themeConfigPanel.Controls.Remove(this.designerTreeView);
385 this.themeConfigPanel.Controls.Remove(this.propertiesGrid);
386 this.designerTreeView.Dock = DockStyle.Left;
387 this.splitter = new Splitter();
388 this.splitter.Dock = DockStyle.Left;
389 this.propertiesGrid.Dock = DockStyle.Fill;
390 this.themeConfigPanel.Controls.AddRange(new Control[] { this.propertiesGrid, this.splitter, this.designerTreeView });
392 this.themePanel.Paint += new PaintEventHandler(OnThemePanelPaint);
393 this.previewButton.Click += new EventHandler(OnPreviewClicked);
394 this.designerTreeView.AfterSelect += new TreeViewEventHandler(OnDesignerSelectionChanged);
395 this.themeLocationButton.Click += new EventHandler(OnThemeLocationClicked);
396 this.okButton.Click += new EventHandler(OnOk);
397 this.propertiesGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(OnThemePropertyChanged);
398 this.themeNameTextBox.TextChanged += new EventHandler(OnThemeChanged);
399 this.themeLocationTextBox.TextChanged += new EventHandler(OnThemeChanged);
401 this.designerTreeView.SelectedNode = (this.designerTreeView.Nodes.Count > 0) ? this.designerTreeView.Nodes[0] : null;
402 this.designerTreeView.SelectedNode.EnsureVisible();
404 ShowPreview = true;
407 private void OnThemeChanged(object sender, EventArgs e)
409 this.themeDirty = true;
412 private void OnThemePropertyChanged(object sender, PropertyValueChangedEventArgs e)
414 this.themeDirty = true;
417 private bool ValidateControls(out string error, out Control control)
419 error = String.Empty;
420 control = null;
422 if (this.themeNameTextBox.Text == null || this.themeNameTextBox.Text.Trim().Length == 0)
424 error = DR.GetString(DR.ThemeNameNotValid);
425 control = this.themeNameTextBox;
426 return false;
429 if (this.themeLocationTextBox.Text == null)
431 error = DR.GetString(DR.ThemePathNotValid);
432 control = this.themeNameTextBox;
433 return false;
436 string path = this.themeLocationTextBox.Text.Trim();
437 if (path.IndexOfAny(Path.GetInvalidPathChars()) >= 0 ||
438 !Path.IsPathRooted(path) ||
439 !Path.HasExtension(path))
441 error = DR.GetString(DR.ThemePathNotValid);
442 control = this.themeLocationTextBox;
443 return false;
446 string fileName = Path.GetFileNameWithoutExtension(path);
447 string extension = Path.GetExtension(path);
448 if (fileName == null || fileName.Trim().Length == 0 ||
449 extension == null || extension.Trim().Length == 0)
451 error = DR.GetString(DR.ThemePathNotValid);
452 control = this.themeLocationTextBox;
453 return false;
456 if (!extension.Equals(WorkflowTheme.DefaultThemeFileExtension.Replace("*", ""), StringComparison.Ordinal))
458 error = DR.GetString(DR.ThemeFileNotXml);
459 control = this.themeLocationTextBox;
460 return false;
463 return true;
466 private void OnOk(object sender, EventArgs e)
468 string error = String.Empty;
469 Control control = null;
470 if (!ValidateControls(out error, out control))
472 DialogResult = DialogResult.None;
473 DesignerHelpers.ShowError(this.serviceProvider, error);
474 if (control != null)
476 TextBox textBox = control as TextBox;
477 if (textBox != null)
479 textBox.SelectionStart = 0;
480 textBox.SelectionLength = (textBox.Text != null) ? textBox.Text.Length : 0;
482 control.Focus();
484 return;
487 //Before we try saving show the warning if the user has changed the theme path
488 if (!this.bufferedTheme.FilePath.Equals(this.themeLocationTextBox.Text.Trim(), StringComparison.OrdinalIgnoreCase))
490 if (DialogResult.No == DesignerHelpers.ShowMessage(this.serviceProvider, DR.GetString(DR.UpdateRelativePaths), DR.GetString(DR.WorkflowDesignerTitle), MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1))
492 DialogResult = DialogResult.None;
493 return;
497 if (this.themeDirty)
501 Cursor.Current = Cursors.WaitCursor;
503 ThemeConfigHelpers.EnsureDesignerThemes(this.serviceProvider, this.bufferedTheme, ThemeConfigHelpers.GetAllTreeNodes(this.designerTreeView));
504 this.bufferedTheme.ReadOnly = false;
505 this.bufferedTheme.Name = this.themeNameTextBox.Text.Trim();
506 this.bufferedTheme.Description = DR.GetString(DR.ThemeDescription);
507 this.bufferedTheme.Save(this.themeLocationTextBox.Text.Trim());
508 this.themeDirty = false;
509 this.bufferedTheme.ReadOnly = true;
511 catch
513 DesignerHelpers.ShowError(this.serviceProvider, DR.GetString(DR.ThemeFileCreationError));
514 this.themeLocationTextBox.SelectionStart = 0;
515 this.themeLocationTextBox.SelectionLength = (this.themeLocationTextBox.Text != null) ? this.themeLocationTextBox.Text.Length : 0;
516 this.themeLocationTextBox.Focus();
517 DialogResult = DialogResult.None;
519 finally
521 Cursor.Current = Cursors.Default;
526 private void OnHelpClicked(object sender, CancelEventArgs e)
528 e.Cancel = true;
529 ShowHelp();
532 protected override void OnHelpRequested(HelpEventArgs e)
534 ShowHelp();
535 e.Handled = true;
538 private void ShowHelp()
540 DesignerHelpers.ShowHelpFromKeyword(this.serviceProvider, typeof(ThemeConfigurationDialog).FullName + ".UI");
543 private void OnThemePanelPaint(object sender, PaintEventArgs e)
545 e.Graphics.DrawRectangle(SystemPens.ControlDark, 0, 0, this.themePanel.ClientSize.Width - 1, this.themePanel.ClientSize.Height - 2);
547 if (this.previewShown)
549 Point top = new Point(this.propertiesGrid.Right + (this.dummyPreviewPanel.Left - this.propertiesGrid.Right) / 2, this.themePanel.Margin.Top);
550 Point bottom = new Point(top.X, this.themePanel.Height - this.themePanel.Margin.Bottom);
551 e.Graphics.DrawLine(SystemPens.ControlDark, top, bottom);
554 Size margin = new Size(8, 8);
555 using (Pen framePen = new Pen(Color.Black, 1))
557 framePen.DashStyle = DashStyle.Dot;
558 e.Graphics.DrawLine(framePen, this.designerPreview.Left - margin.Width, this.designerPreview.Top - 1, this.designerPreview.Right + margin.Width, this.designerPreview.Top - 1);
559 e.Graphics.DrawLine(framePen, this.designerPreview.Left - margin.Width, this.designerPreview.Bottom + 1, this.designerPreview.Right + margin.Width, this.designerPreview.Bottom + 1);
560 e.Graphics.DrawLine(framePen, this.designerPreview.Left - 1, this.designerPreview.Top - margin.Height, this.designerPreview.Left - 1, this.designerPreview.Bottom + margin.Height);
561 e.Graphics.DrawLine(framePen, this.designerPreview.Right + 1, this.designerPreview.Top - margin.Height, this.designerPreview.Right + 1, this.designerPreview.Bottom + margin.Height);
565 private void OnDesignerSelectionChanged(object sender, TreeViewEventArgs eventArgs)
567 //We need to select the theme of the selected designer
568 Type activityType = (eventArgs.Node != null && typeof(Activity).IsAssignableFrom(eventArgs.Node.Tag as System.Type)) ? eventArgs.Node.Tag as System.Type : null;
569 IDesigner previewedDesigner = this.designerPreview.UpdatePreview(activityType);
571 object[] selectedObjects = null;
572 if (activityType == null)
574 if (eventArgs.Node != null)
575 selectedObjects = (eventArgs.Node.Parent == null) ? new object[] { this.bufferedTheme.AmbientTheme } : ThemeConfigHelpers.GetDesignerThemes(this.serviceProvider, this.bufferedTheme, eventArgs.Node);
577 else
579 selectedObjects = (previewedDesigner != null) ? new object[] { this.bufferedTheme.GetDesignerTheme(previewedDesigner as ActivityDesigner) } : null;
582 this.propertiesGrid.SelectedObjects = selectedObjects;
585 private void OnPreviewClicked(object sender, EventArgs e)
587 ShowPreview = !ShowPreview;
590 private void OnThemeLocationClicked(object sender, EventArgs e)
592 SaveFileDialog fileDialog = new SaveFileDialog();
593 fileDialog.AddExtension = true;
594 fileDialog.DefaultExt = WorkflowTheme.DefaultThemeFileExtension;
595 fileDialog.Filter = DR.GetString(DR.ThemeFileFilter);
596 fileDialog.RestoreDirectory = false;
597 if (fileDialog.ShowDialog(this) == DialogResult.OK)
599 this.themeLocationTextBox.Text = fileDialog.FileName;
603 private bool ShowPreview
607 return this.previewShown;
612 this.previewShown = value;
613 this.previewLabel.Visible = this.previewShown;
614 this.designerPreview.Visible = this.previewShown;
616 if (this.previewShown)
618 this.themePanel.Width = this.designerPreview.Right + ((this.designerPreview.Left - this.propertiesGrid.Right) / 2);
619 this.previewButton.Text = DR.GetString(DR.Preview) + " <<";
621 else
623 this.themePanel.Width = this.themeConfigPanel.Right + this.themeConfigPanel.Left;
624 this.previewButton.Text = DR.GetString(DR.Preview) + " >>";
626 Width = this.themePanel.Right + this.themePanel.Left + Margin.Left + Margin.Right;
627 this.themePanel.Invalidate();
631 private void OnOperatingSystemSettingsChanged(object sender, UserPreferenceChangedEventArgs e)
635 if (e.Category == UserPreferenceCategory.Color || e.Category == UserPreferenceCategory.VisualStyle)
636 Font = StandardFont;
638 #endregion
640 #region Class ThemeHelpers
641 private static class ThemeConfigHelpers
643 internal static void PopulateActivities(IServiceProvider serviceProvider, TreeView treeView)
645 List<Type> activityTypes = new List<Type>();
647 //***************STOCK TYPES*************
648 List<String> stockActivityTypeNames = new List<string>();
649 stockActivityTypeNames.Add(DesignerHelpers.SequentialWorkflowTypeRef);
650 stockActivityTypeNames.Add(DesignerHelpers.StateMachineWorkflowTypeRef);
651 stockActivityTypeNames.Add(DesignerHelpers.IfElseBranchTypeRef);
652 stockActivityTypeNames.Add(typeof(FaultHandlersActivity).AssemblyQualifiedName);
653 stockActivityTypeNames.Add(DesignerHelpers.EventHandlersTypeRef);
654 stockActivityTypeNames.Add(typeof(CompensationHandlerActivity).AssemblyQualifiedName);
655 stockActivityTypeNames.Add(typeof(CancellationHandlerActivity).AssemblyQualifiedName);
657 foreach (string stockTypeName in stockActivityTypeNames)
659 Type stockType = Type.GetType(stockTypeName, false);
660 if (stockType == null)
661 Debug.Assert(false, string.Format(CultureInfo.CurrentCulture, "Could not load type '{0}'", stockTypeName));
662 else
663 activityTypes.Add(stockType);
666 //***************NON PREVIWABLE DESIGNER TYPES*************
667 IList<Type> nonpreviewableDesignerTypes = new List<Type>();
669 //These designer might be designers such as CADesigner which we eliminated
670 //We have just kept the code so that in future if this functionality is needed
671 //we can add it
673 //Populate the designer combobox
674 treeView.BeginUpdate();
675 treeView.Nodes.Clear();
677 //Work around: ***WE DISPLAY THE COMMON PROPERTIES FOR WORKFLOW AND APPLY THEM RECURSIVELY TO DESIGNERS
678 TreeNode workflowNode = new TreeNode(DR.GetString(DR.WorkflowDesc));
679 treeView.Nodes.Add(workflowNode);
681 //Now we go thru the toolbox items and get all the items which are not in our assembly
682 IToolboxService toolboxService = serviceProvider.GetService(typeof(IToolboxService)) as IToolboxService;
683 ITypeProviderCreator typeProviderCreator = serviceProvider.GetService(typeof(ITypeProviderCreator)) as ITypeProviderCreator;
684 if (toolboxService != null && typeProviderCreator != null)
686 ToolboxItemCollection toolboxItems = toolboxService.GetToolboxItems();
687 foreach (ToolboxItem toolboxItem in toolboxItems)
689 bool customWinOEActivityType = (toolboxItem is ActivityToolboxItem);
690 if (!customWinOEActivityType)
692 foreach (ToolboxItemFilterAttribute filter in toolboxItem.Filter)
694 if (filter.FilterString.StartsWith("Microsoft.Workflow.VSDesigner", StringComparison.OrdinalIgnoreCase) ||
695 filter.FilterString.StartsWith("System.Workflow.ComponentModel", StringComparison.OrdinalIgnoreCase))
697 customWinOEActivityType = true;
698 break;
703 if (customWinOEActivityType)
705 Type type = null;
706 Assembly assembly = typeProviderCreator.GetTransientAssembly(toolboxItem.AssemblyName);
707 if (assembly != null)
708 type = assembly.GetType(toolboxItem.TypeName);
709 if (type != null)
711 ConstructorInfo[] constructors = type.GetConstructors();
712 foreach (ConstructorInfo constructor in constructors)
714 if (constructor.IsPublic && constructor.GetParameters().GetLength(0) == 0)
715 activityTypes.Add(type);
722 foreach (Type type in activityTypes)
724 Type designerBaseType = (type.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner);
725 Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, type, designerBaseType);
726 if (designerType != null && !nonpreviewableDesignerTypes.Contains(designerType))
728 object[] attribs = designerType.GetCustomAttributes(typeof(ActivityDesignerThemeAttribute), true);
729 ActivityDesignerThemeAttribute themeAttrib = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as ActivityDesignerThemeAttribute : null;
730 if (themeAttrib != null)
732 Image image = ActivityToolboxItem.GetToolboxImage(type);
733 if (treeView.ImageList == null)
735 treeView.ImageList = new ImageList();
736 treeView.ImageList.ColorDepth = ColorDepth.Depth32Bit;
737 Image standardImage = DR.GetImage(DR.Activity) as Image;
738 treeView.ImageList.Images.Add(standardImage, AmbientTheme.TransparentColor);
741 TreeNode parentNode = ThemeConfigHelpers.GetCatagoryNodeForDesigner(designerType, ThemeConfigHelpers.GetAllTreeNodes(treeView));
742 if (parentNode != null)
744 int imageIndex = (image != null) ? treeView.ImageList.Images.Add(image, AmbientTheme.TransparentColor) : 0;
745 TreeNode nodeToInsert = (imageIndex >= 0) ? new TreeNode(ActivityToolboxItem.GetToolboxDisplayName(type), imageIndex, imageIndex) : new TreeNode(ActivityToolboxItem.GetToolboxDisplayName(type));
746 nodeToInsert.Tag = type;
748 //We always make sure that cata----es are at the end
749 int index = parentNode.Nodes.Count - 1;
750 while (index >= 0 && parentNode.Nodes[index].Tag is System.Type)
751 index = index - 1;
752 parentNode.Nodes.Insert(index, nodeToInsert);
758 treeView.TreeViewNodeSorter = new ThemeTreeNodeComparer();
759 treeView.Sort();
760 treeView.Nodes[0].ExpandAll();
761 treeView.EndUpdate();
764 internal static TreeNode GetCatagoryNodeForDesigner(Type designerType, TreeNode[] treeNodes)
766 if (designerType == null)
767 throw new ArgumentNullException("designerType");
768 if (treeNodes == null)
769 throw new ArgumentNullException("treeNodes");
770 if (treeNodes.Length == 0)
771 throw new ArgumentException(SR.GetString(SR.Error_InvalidArgumentValue), "treeNodes");
773 CategoryAttribute parentCatagoryAttribute = null;
774 CategoryAttribute designerCatagoryAttribute = null;
775 Type baseType = designerType;
776 while (baseType != typeof(object) && parentCatagoryAttribute == null)
778 object[] attribs = baseType.GetCustomAttributes(typeof(CategoryAttribute), false);
779 if (attribs != null && attribs.GetLength(0) > 0)
781 if (designerCatagoryAttribute == null)
782 designerCatagoryAttribute = attribs[0] as CategoryAttribute;
783 else
784 parentCatagoryAttribute = attribs[0] as CategoryAttribute;
786 baseType = baseType.BaseType;
789 if (designerCatagoryAttribute == null)
790 return null;
792 //Search for the catagory
793 TreeNode catagoryNode = null;
794 TreeNode parentCatagoryTreeNode = treeNodes[0];
796 foreach (TreeNode item in treeNodes)
798 if (parentCatagoryAttribute != null && parentCatagoryAttribute.Category == item.Text && (item.Tag == null || !typeof(Activity).IsAssignableFrom(item.Tag.GetType())))
799 parentCatagoryTreeNode = item;
801 //We found the catagory
802 if (designerCatagoryAttribute.Category == item.Text && (item.Tag == null || !typeof(Activity).IsAssignableFrom(item.Tag.GetType())))
804 catagoryNode = item;
805 break;
809 if (catagoryNode == null)
811 Debug.Assert(parentCatagoryTreeNode != null);
812 if (parentCatagoryTreeNode != null)
814 //Work around : ***WE DISPLAY THE COMMON PROPERTIES FROM KNOWN DESIGNERCATA----ES
815 //WE WILL EVENTUALLY REMOVE THIS WHEN WE CREATE AN MECHANISM TO SHARE COMMON
816 //PROPERTIES IN THEMES
817 catagoryNode = new TreeNode(designerCatagoryAttribute.Category);
818 parentCatagoryTreeNode.Nodes.Add(catagoryNode);
822 return catagoryNode;
825 internal static DesignerTheme[] GetDesignerThemes(IServiceProvider serviceProvider, WorkflowTheme workflowTheme, TreeNode selectedNode)
827 ArrayList designerThemes = new ArrayList();
828 Queue<TreeNode> nodes = new Queue<TreeNode>();
829 nodes.Enqueue(selectedNode);
830 while (nodes.Count > 0)
832 TreeNode treeNode = nodes.Dequeue();
833 Type activityType = treeNode.Tag as System.Type;
834 if (activityType != null)
836 Type designerBaseType = (activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner);
837 Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, activityType, designerBaseType);
838 if (designerType != null)
840 DesignerTheme designerTheme = workflowTheme.GetTheme(designerType);
841 if (designerTheme != null)
842 designerThemes.Add(designerTheme);
845 else
847 foreach (TreeNode childNode in treeNode.Nodes)
848 nodes.Enqueue(childNode);
852 return ((DesignerTheme[])designerThemes.ToArray(typeof(DesignerTheme)));
855 internal static TreeNode[] GetAllTreeNodes(TreeView treeView)
857 List<TreeNode> items = new List<TreeNode>();
858 Queue<TreeNodeCollection> nodeCollections = new Queue<TreeNodeCollection>();
859 nodeCollections.Enqueue(treeView.Nodes);
860 while (nodeCollections.Count > 0)
862 TreeNodeCollection nodeCollection = nodeCollections.Dequeue();
863 foreach (TreeNode treeNode in nodeCollection)
865 items.Add(treeNode);
866 if (treeNode.Nodes.Count > 0)
867 nodeCollections.Enqueue(treeNode.Nodes);
871 return items.ToArray();
874 internal static void EnsureDesignerThemes(IServiceProvider serviceProvider, WorkflowTheme workflowTheme, TreeNode[] items)
876 //We need to recurse thru the themes and make sure that we have all the designer themes created
877 foreach (TreeNode item in items)
879 DesignerTheme designerTheme = null;
880 Type activityType = item.Tag as Type;
881 if (activityType != null)
883 Type designerBaseType = (activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase)) ? typeof(IRootDesigner) : typeof(IDesigner);
884 Type designerType = ActivityDesigner.GetDesignerType(serviceProvider, activityType, designerBaseType);
885 if (designerType != null)
886 designerTheme = workflowTheme.GetTheme(designerType);
891 #endregion
893 #region Class ThemeTreeNodeComparer
894 internal sealed class ThemeTreeNodeComparer : IComparer
896 #region IComparer Members
897 int IComparer.Compare(object x, object y)
899 TreeNode treeNode1 = x as TreeNode;
900 TreeNode treeNode2 = y as TreeNode;
902 if (treeNode1.Nodes.Count > treeNode2.Nodes.Count)
903 return 1;
904 else
905 return String.Compare(treeNode1.Text, treeNode2.Text, StringComparison.CurrentCulture);
907 #endregion
909 #endregion
911 #region Class DesignerPreview
912 internal sealed class DesignerPreview : UserControl
914 private ThemeConfigurationDialog parent = null;
915 private PreviewDesignSurface surface = null;
917 internal DesignerPreview(ThemeConfigurationDialog parent)
919 BackColor = Color.White;
920 this.parent = parent;
923 protected override void OnLoad(EventArgs e)
925 base.OnLoad(e);
927 SuspendLayout();
929 this.surface = new PreviewDesignSurface(this.parent.serviceProvider);
930 PreviewWorkflowDesignerLoader loader = new PreviewWorkflowDesignerLoader();
931 this.surface.BeginLoad(loader);
933 //Add the root activity
934 IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost;
935 Debug.Assert(host != null);
938 Activity rootDecl = host.CreateComponent(Type.GetType(DesignerHelpers.SequentialWorkflowTypeRef)) as Activity;
939 rootDecl.Name = "ThemeSequentialWorkflow";
940 WorkflowDesignerLoader.AddActivityToDesigner(this.surface, rootDecl as Activity);
942 //Create the readonly workflow
943 ReadonlyWorkflow workflowView = new ReadonlyWorkflow(this.parent, this.surface as IServiceProvider);
944 workflowView.TabStop = false;
945 workflowView.Dock = DockStyle.Fill;
946 Controls.Add(workflowView);
948 host.Activate();
950 ResumeLayout(true);
953 protected override void Dispose(bool disposing)
955 if (disposing && this.surface != null)
957 IDesignerHost host = GetService(typeof(IDesignerHost)) as IDesignerHost;
958 if (host != null && host.RootComponent != null)
959 WorkflowDesignerLoader.RemoveActivityFromDesigner(this.surface, host.RootComponent as Activity);
961 ReadonlyWorkflow workflowView = (Controls.Count > 0) ? Controls[0] as ReadonlyWorkflow : null;
962 Controls.Clear();
963 if (workflowView != null)
965 workflowView.Dispose();
966 workflowView = null;
969 this.surface.Dispose();
970 this.surface = null;
973 base.Dispose(disposing);
976 internal IDesigner UpdatePreview(Type activityType)
978 bool dummyPreview = false; //if we have a dummy preview activity
979 IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost;
980 Debug.Assert(host != null);
982 CompositeActivity rootDecl = host.RootComponent as CompositeActivity;
983 Debug.Assert(rootDecl != null);
984 if (host == null || rootDecl == null)
985 return null;
987 IComponent previewActivity = null;
990 //Remove earlier activities
991 while (rootDecl.Activities.Count > 0)
993 Activity declToDelete = rootDecl.Activities[0];
994 rootDecl.Activities.Remove(declToDelete);
995 WorkflowDesignerLoader.RemoveActivityFromDesigner(this.surface, declToDelete);
998 //Add new activities to preview
999 if (activityType == null || activityType.FullName.Equals(DesignerHelpers.SequentialWorkflowTypeRef, StringComparison.OrdinalIgnoreCase))
1001 AddDummyActivity(rootDecl as CompositeActivity, Type.GetType(DesignerHelpers.CodeActivityTypeRef));
1002 dummyPreview = true;
1004 else
1006 IComponent[] components = null;
1007 object[] attribs = activityType.GetCustomAttributes(typeof(ToolboxItemAttribute), false);
1008 ToolboxItemAttribute toolboxItemAttrib = (attribs != null && attribs.GetLength(0) > 0) ? attribs[0] as ToolboxItemAttribute : null;
1009 if (toolboxItemAttrib != null && toolboxItemAttrib.ToolboxItemType != null && typeof(ActivityToolboxItem).IsAssignableFrom(toolboxItemAttrib.ToolboxItemType))
1011 ActivityToolboxItem item = Activator.CreateInstance(toolboxItemAttrib.ToolboxItemType, new object[] { activityType }) as ActivityToolboxItem;
1012 components = item.CreateComponents(host);
1015 if (components == null)
1016 components = new IComponent[] { Activator.CreateInstance(activityType) as IComponent };
1018 Activity activity = (components != null && components.Length > 0) ? components[0] as Activity : null;
1019 if (activity != null)
1021 rootDecl.Activities.Add(activity);
1022 EnsureUniqueId(activity);
1024 WorkflowDesignerLoader.AddActivityToDesigner(this.surface, activity);
1025 CompositeActivityDesigner compositeDesigner = host.GetDesigner(rootDecl) as CompositeActivityDesigner;
1026 ActivityDesigner activityDesigner = host.GetDesigner(activity) as ActivityDesigner;
1027 if (compositeDesigner != null && activityDesigner != null)
1028 compositeDesigner.EnsureVisibleContainedDesigner(activityDesigner);
1042 ISelectionService selectionService = host.GetService(typeof(ISelectionService)) as ISelectionService;
1043 if (selectionService != null)
1044 selectionService.SetSelectedComponents(new IComponent[] { rootDecl });
1046 ReadonlyWorkflow workflowView = (Controls.Count > 0) ? Controls[0] as ReadonlyWorkflow : null;
1047 if (workflowView != null)
1048 workflowView.PerformLayout();
1050 previewActivity = (rootDecl.Activities.Count > 0 && !dummyPreview) ? rootDecl.Activities[0] : rootDecl;
1052 catch
1056 return (previewActivity != null) ? host.GetDesigner(previewActivity) : null;
1059 private void AddDummyActivity(CompositeActivity parentActivity, Type activityType)
1061 IDesignerHost host = this.surface.GetService(typeof(IDesignerHost)) as IDesignerHost;
1062 Debug.Assert(host != null);
1063 if (host == null)
1064 return;
1066 Activity dummyActivity = Activator.CreateInstance(activityType) as Activity;
1067 Debug.Assert(dummyActivity != null);
1068 if (dummyActivity == null)
1069 return;
1071 parentActivity.Activities.Add(dummyActivity);
1072 EnsureUniqueId(dummyActivity);
1073 WorkflowDesignerLoader.AddActivityToDesigner(this.surface, dummyActivity);
1076 private void EnsureUniqueId(Activity addedActivity)
1078 Dictionary<string, int> identifiers = new Dictionary<string, int>();
1079 Queue<Activity> Activities = new Queue<Activity>();
1080 Activities.Enqueue(addedActivity);
1081 while (Activities.Count > 0)
1083 Activity Activity = Activities.Dequeue();
1084 string fullTypeName = Activity.GetType().FullName;
1086 int id = (identifiers.ContainsKey(fullTypeName)) ? identifiers[fullTypeName] : 1;
1087 Activity.Name = Activity.GetType().Name + id.ToString(CultureInfo.InvariantCulture);
1088 id += 1;
1090 if (identifiers.ContainsKey(fullTypeName))
1091 identifiers[fullTypeName] = id;
1092 else
1093 identifiers.Add(fullTypeName, id);
1095 CompositeActivity compositeActivity = Activity as CompositeActivity;
1096 if (compositeActivity != null)
1098 foreach (Activity activity in compositeActivity.Activities)
1099 Activities.Enqueue(activity);
1104 #region Class PreviewDesignSurface
1105 private sealed class PreviewDesignSurface : DesignSurface
1107 internal PreviewDesignSurface(IServiceProvider parentProvider)
1108 : base(new PreviewDesignerServiceProvider(parentProvider))
1110 ITypeProvider typeProvider = GetService(typeof(ITypeProvider)) as ITypeProvider;
1111 if (typeProvider == null)
1113 TypeProvider provider = new TypeProvider(this);
1114 provider.AddAssemblyReference(typeof(string).Assembly.Location);
1115 ServiceContainer.AddService(typeof(ITypeProvider), provider, true);
1119 protected override IDesigner CreateDesigner(IComponent component, bool rootDesigner)
1121 IDesigner designer = base.CreateDesigner(component, rootDesigner);
1122 Activity activity = component as Activity;
1123 if (designer == null && !rootDesigner && activity != null)
1124 designer = ActivityDesigner.CreateDesigner(activity.Site, activity);
1125 return designer;
1128 #region Class PreviewDesignerServiceProvider
1129 private sealed class PreviewDesignerServiceProvider : IServiceProvider
1131 private IServiceProvider serviceProvider;
1133 internal PreviewDesignerServiceProvider(IServiceProvider serviceProvider)
1135 this.serviceProvider = serviceProvider;
1138 #region IServiceProvider Members
1139 object IServiceProvider.GetService(Type serviceType)
1141 if (serviceType == typeof(IPropertyValueUIService))
1142 return null;
1143 return this.serviceProvider.GetService(serviceType);
1145 #endregion
1147 #endregion
1149 #endregion
1151 #region Class PreviewWorkflowDesignerLoader
1152 private class PreviewWorkflowDesignerLoader : WorkflowDesignerLoader
1154 public override TextReader GetFileReader(string filePath)
1156 return null;
1159 public override TextWriter GetFileWriter(string filePath)
1161 return null;
1164 public override string FileName
1168 return String.Empty;
1172 #endregion
1174 #region Class ReadOnly Workflow
1175 private class ReadonlyWorkflow : WorkflowView
1177 private ThemeConfigurationDialog themeConfigDialog = null;
1179 internal ReadonlyWorkflow(ThemeConfigurationDialog themeConfigDialog, IServiceProvider serviceProvider)
1180 : base(serviceProvider)
1182 this.themeConfigDialog = themeConfigDialog;
1183 this.themeConfigDialog.propertiesGrid.PropertyValueChanged += new PropertyValueChangedEventHandler(OnThemePropertyChanged);
1184 this.EnableFitToScreen = false;
1186 AddDesignerMessageFilter(new ReadonlyMessageFilter());
1189 protected override void Dispose(bool disposing)
1191 base.Dispose(disposing);
1193 if (this.themeConfigDialog != null && this.themeConfigDialog.propertiesGrid != null)
1194 this.themeConfigDialog.propertiesGrid.PropertyValueChanged -= new PropertyValueChangedEventHandler(OnThemePropertyChanged);
1197 protected override void OnPaint(PaintEventArgs e)
1199 if (this.themeConfigDialog == null)
1201 base.OnPaint(e);
1202 return;
1205 using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme))
1206 base.OnPaint(e);
1209 protected override void OnLayout(LayoutEventArgs levent)
1211 if (this.themeConfigDialog != null)
1213 using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme))
1214 base.OnLayout(levent);
1216 Size maxExtent = ActiveLayout.Extent;
1217 Size size = Size;
1218 PointF zoom = new PointF((float)size.Width / (float)maxExtent.Width, (float)size.Height / (float)maxExtent.Height);
1219 Zoom = Convert.ToInt32((Math.Min(zoom.X, zoom.Y) * 100));
1223 private void OnThemePropertyChanged(object sender, PropertyValueChangedEventArgs e)
1225 if (this.themeConfigDialog != null)
1227 using (BufferedTheme bufferedTheme = new BufferedTheme(this.themeConfigDialog.bufferedTheme))
1228 base.OnThemeChange(WorkflowTheme.CurrentTheme, EventArgs.Empty);
1232 #region Class BufferedTheme
1233 private sealed class BufferedTheme : IDisposable
1235 private WorkflowTheme oldTheme = null;
1237 internal BufferedTheme(WorkflowTheme themeToApply)
1239 if (themeToApply != null && WorkflowTheme.CurrentTheme != themeToApply)
1241 WorkflowTheme.EnableChangeNotification = false;
1242 this.oldTheme = WorkflowTheme.CurrentTheme;
1243 WorkflowTheme.CurrentTheme = themeToApply;
1247 void IDisposable.Dispose()
1249 if (this.oldTheme != null && WorkflowTheme.CurrentTheme != this.oldTheme)
1251 WorkflowTheme.CurrentTheme.ReadOnly = false; //this was themeToApply passed into constructor, need to make it r/w again
1252 WorkflowTheme.CurrentTheme = this.oldTheme;
1253 WorkflowTheme.EnableChangeNotification = true;
1257 #endregion
1259 #endregion
1261 #endregion