1 //-----------------------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation. All rights reserved.
3 //-----------------------------------------------------------------------------
5 namespace System.Activities.Presentation
7 using System.Collections;
8 using System.Collections.Generic;
10 using System.ComponentModel;
11 using Microsoft.VisualBasic.Activities;
12 using System.Activities.Presentation.View;
13 using System.Activities.Expressions;
14 using System.Reflection;
15 using System.Collections.ObjectModel;
17 class NamespaceListPropertyDescriptor : PropertyDescriptor
19 public const string ImportCollectionPropertyName = "Imports";
20 public const string AvailableNamespacesPropertyName = "AvailableNamespaces";
21 public const string NamespacePropertyName = "Namespace";
25 public NamespaceListPropertyDescriptor(object instance)
26 : base(ImportCollectionPropertyName, null)
28 this.instance = instance;
31 public override Type ComponentType
33 get { return this.instance.GetType(); }
36 public override bool IsReadOnly
44 public override Type PropertyType
48 return typeof(NamespaceList);
52 public override bool IsBrowsable
60 public override bool CanResetValue(object component)
65 public override object GetValue(object component)
67 VisualBasicSettings settings = VisualBasic.GetSettings(component);
68 IList<AssemblyReference> references;
69 IList<string> namespaces = NamespaceHelper.GetTextExpressionNamespaces(component, out references);
70 if ((namespaces != null) && ((namespaces.Count > 0) || ((namespaces.Count == 0) && (settings == null))))
72 return new TextExpressionNamespaceList(namespaces, references);
76 Fx.Assert(settings != null, "Either VB settings or new TextExpression attached properties should be set");
77 return new VisualBasicNamespaceList(settings.ImportReferences);
81 public override void ResetValue(object component)
83 IList<AssemblyReference> references;
84 IList<string> importedNamespaces = NamespaceHelper.GetTextExpressionNamespaces(component, out references);
85 if (importedNamespaces != null)
87 NamespaceHelper.SetTextExpressionNamespaces(component, null, null);
91 NamespaceHelper.SetVisualBasicSettings(component, null);
95 public override void SetValue(object component, object value)
97 NamespaceList namespaceList = value as NamespaceList;
98 if (namespaceList != null)
100 if (namespaceList is VisualBasicNamespaceList)
102 VisualBasicNamespaceList visualBasicNamespaces = namespaceList as VisualBasicNamespaceList;
103 VisualBasicSettings settings = new VisualBasicSettings();
104 settings.ImportReferences.UnionWith(visualBasicNamespaces.VisualBasicImports);
105 NamespaceHelper.SetVisualBasicSettings(component, settings);
109 Fx.Assert(namespaceList is TextExpressionNamespaceList, "The namespace list must be either of VisualBaiscSettings or TextExpression attached properties.");
110 TextExpressionNamespaceList textExpressionNamespace = namespaceList as TextExpressionNamespaceList;
111 NamespaceHelper.SetTextExpressionNamespaces(
113 textExpressionNamespace.TextExpressionNamespaces,
114 textExpressionNamespace.TextExpressionReferences);
119 this.ResetValue(component);
123 public override bool ShouldSerializeValue(object component)
125 throw FxTrace.Exception.AsError(new NotSupportedException());
128 protected override void FillAttributes(IList attributeList)
130 attributeList.Add(new BrowsableAttribute(false));
131 base.FillAttributes(attributeList);
137 public string Namespace
143 //Used by screen reader
144 public override string ToString()
146 return this.Namespace;
150 abstract class NamespaceList : IList
152 //list of uniqueNamespaces, the element is a tuple of the namespace and a arbitary data for consumer to use
153 List<NamespaceData> uniqueNamespaces;
154 Dictionary<string, List<string>> availableNamespaces;
156 protected List<NamespaceData> UniqueNamespaces
160 if (this.uniqueNamespaces == null)
162 this.uniqueNamespaces = new List<NamespaceData>();
164 return this.uniqueNamespaces;
168 public Dictionary<string, List<string>> AvailableNamespaces
172 if (availableNamespaces == null)
174 availableNamespaces = new Dictionary<string, List<string>>();
177 return availableNamespaces;
181 internal int Lookup(string ns)
183 for (int i = 0; i < this.UniqueNamespaces.Count; i++)
185 if (this.UniqueNamespaces[i].Namespace == ns)
194 public int Add(object value)
196 NamespaceData ns = value as NamespaceData;
200 throw FxTrace.Exception.AsError(new ArgumentException(SR.NamespaceListArgumentMustBeNamespaceData, "value"));
203 if (Lookup(ns.Namespace) == -1)
206 return ((IList)this.UniqueNamespaces).Add(ns);
217 this.UniqueNamespaces.Clear();
220 public bool Contains(object value)
222 return ((IList)this.UniqueNamespaces).Contains(value);
225 public int IndexOf(object value)
227 return ((IList)this.UniqueNamespaces).IndexOf(value);
230 public void Insert(int index, object value)
232 NamespaceData ns = value as NamespaceData;
235 throw FxTrace.Exception.AsError(new ArgumentException(SR.NamespaceListArgumentMustBeNamespaceData, "value"));
238 if (Lookup(ns.Namespace) == -1)
240 this.UniqueNamespaces.Insert(index, ns);
241 this.InsertCore(index, ns);
245 throw FxTrace.Exception.AsError(new InvalidOperationException());
249 public bool IsFixedSize
251 get { return false; }
254 public bool IsReadOnly
256 get { return false; }
259 public void Remove(object value)
261 NamespaceData ns = value as NamespaceData;
264 throw FxTrace.Exception.AsError(new ArgumentException(SR.NamespaceListArgumentMustBeNamespaceData, "value"));
267 int index = this.Lookup(ns.Namespace);
274 public void RemoveAt(int index)
276 NamespaceData ns = this.UniqueNamespaces[index];
278 RemoveNamespaceFromSet(ns.Namespace);
280 this.UniqueNamespaces.RemoveAt(index);
283 public object this[int index]
287 return this.UniqueNamespaces[index];
291 NamespaceData ns = value as NamespaceData;
294 throw FxTrace.Exception.AsError(new ArgumentException(SR.NamespaceListArgumentMustBeNamespaceData, "value"));
297 if (Lookup(ns.Namespace) == -1)
299 this.SetValueAt(index, ns);
300 this.UniqueNamespaces[index] = ns;
304 throw FxTrace.Exception.AsError(new InvalidOperationException(SR.NamespaceListNoDuplicate));
309 public void CopyTo(Array array, int index)
311 ((IList)this.UniqueNamespaces).CopyTo(array, index);
316 get { return this.UniqueNamespaces.Count; }
319 public bool IsSynchronized
321 get { return false; }
324 public object SyncRoot
329 public IEnumerator GetEnumerator()
331 return this.UniqueNamespaces.GetEnumerator();
334 public void UpdateAssemblyInfo(string importedNamespace)
336 this.UpdateAssemblyInfoCore(importedNamespace);
339 protected abstract void AddCore(NamespaceData ns);
340 protected abstract void ClearCore();
341 protected abstract void InsertCore(int index, NamespaceData ns);
342 protected abstract void RemoveNamespaceFromSet(string ns);
343 protected abstract void SetValueAt(int index, NamespaceData ns);
344 protected abstract void UpdateAssemblyInfoCore(string importedNamespace);
347 class VisualBasicNamespaceList : NamespaceList
349 //Since XAML generated by designer will almost always have some designer type in it, designer namespaces will appear in XAML.
350 //And because Runtime design could not destinguish namespaces coming from XAML serialization between namespaces added by users,
351 //designer namespaces will show up in import designer. This is bad user experience because most WF project won't reference designer
352 //assembly. We could safely assume that customers won't use designer namespaces and type in their WF expressions, so we simply
353 //---- designer namespaces out of the namespace list
354 static readonly string[] ----edAssemblies = new string[]
356 typeof(ViewStateService).Assembly.GetName().FullName,
357 typeof(ViewStateService).Assembly.GetName().Name,
360 static readonly Collection<string> FrameworkAssemblies = new Collection<string>
362 typeof(Activity).Assembly.GetName().FullName,
363 typeof(Activity).Assembly.GetName().Name,
366 static readonly Collection<string> ----sedNamespaces = new Collection<string>
368 "System.Activities.Composition",
369 "System.Activities.Debugger.Symbol"
372 public VisualBasicNamespaceList(ISet<VisualBasicImportReference> importReferences)
374 this.VisualBasicImports = importReferences;
376 foreach (string ----edAssembly in ----edAssemblies)
378 RemoveAssemblyFromSet(----edAssembly);
380 foreach (VisualBasicImportReference import in importReferences)
382 if (!(----sedNamespaces.Contains(import.Import) && FrameworkAssemblies.Contains(import.Assembly)))
384 if (Lookup(import.Import) == -1)
386 this.UniqueNamespaces.Add(new NamespaceData { Namespace = import.Import });
392 internal ISet<VisualBasicImportReference> VisualBasicImports
398 IEnumerable<VisualBasicImportReference> GetVisualBasicImportReferences(string importNamespace)
400 List<VisualBasicImportReference> imports = new List<VisualBasicImportReference>();
401 List<string> assemblies;
402 //in rehost cases or when some assembiles are not referenced, we may not find that namespace
403 if (!this.AvailableNamespaces.TryGetValue(importNamespace, out assemblies))
408 foreach (string assembly in assemblies)
410 imports.Add(new VisualBasicImportReference
412 Import = importNamespace,
419 protected override void UpdateAssemblyInfoCore(string importedNamespace)
421 if (this.VisualBasicImports != null)
423 if (this.Lookup(importedNamespace) != -1)
425 this.VisualBasicImports.UnionWith(GetVisualBasicImportReferences(importedNamespace));
429 Fx.Assert("UpdateAssemblyInfor should only be called for existed namespace");
434 protected override void RemoveNamespaceFromSet(string ns)
436 List<VisualBasicImportReference> toRemoves = new List<VisualBasicImportReference>();
437 foreach (VisualBasicImportReference import in this.VisualBasicImports)
439 if (import.Import == ns)
441 toRemoves.Add(import);
445 foreach (VisualBasicImportReference toRemove in toRemoves)
447 this.VisualBasicImports.Remove(toRemove);
451 private void RemoveAssemblyFromSet(string assembly)
453 List<VisualBasicImportReference> toRemoves = new List<VisualBasicImportReference>();
454 foreach (VisualBasicImportReference import in this.VisualBasicImports)
456 if (import.Assembly == assembly)
458 toRemoves.Add(import);
462 foreach (VisualBasicImportReference toRemove in toRemoves)
464 this.VisualBasicImports.Remove(toRemove);
468 protected override void AddCore(NamespaceData ns)
470 this.VisualBasicImports.UnionWith(GetVisualBasicImportReferences(ns.Namespace));
473 protected override void ClearCore()
475 this.VisualBasicImports.Clear();
478 protected override void InsertCore(int index, NamespaceData ns)
480 this.VisualBasicImports.UnionWith(GetVisualBasicImportReferences(ns.Namespace));
483 protected override void SetValueAt(int index, NamespaceData ns)
485 RemoveNamespaceFromSet(this.UniqueNamespaces[index].Namespace);
486 this.VisualBasicImports.UnionWith(GetVisualBasicImportReferences(ns.Namespace));
490 class TextExpressionNamespaceList : NamespaceList
492 public TextExpressionNamespaceList(IList<string> importedNamespaces, IList<AssemblyReference> references)
494 this.TextExpressionNamespaces = importedNamespaces;
495 this.TextExpressionReferences = references;
496 foreach (string importedNamespace in importedNamespaces)
498 if (Lookup(importedNamespace) == -1)
500 this.UniqueNamespaces.Add(new NamespaceData { Namespace = importedNamespace });
505 internal IList<string> TextExpressionNamespaces
511 internal IList<AssemblyReference> TextExpressionReferences
518 protected override void RemoveNamespaceFromSet(string ns)
520 this.TextExpressionNamespaces.Remove(ns);
523 internal void RemoveAssemblyFromSet(string assembly)
525 AssemblyReference toRemove = null;
526 foreach (AssemblyReference reference in this.TextExpressionReferences)
528 if (reference.AssemblyName.Name == assembly)
530 toRemove = reference;
534 if (toRemove != null)
536 this.TextExpressionReferences.Remove(toRemove);
540 private void AddAssemblyToSet(string assembly)
542 bool isExisted = false;
543 foreach (AssemblyReference reference in this.TextExpressionReferences)
545 if (reference.AssemblyName.Name == assembly)
553 this.TextExpressionReferences.Add(new AssemblyReference { AssemblyName = new AssemblyName(assembly) });
557 protected override void AddCore(NamespaceData ns)
559 this.InsertCore(this.TextExpressionNamespaces.Count, ns);
562 protected override void ClearCore()
564 this.TextExpressionNamespaces.Clear();
567 protected override void InsertCore(int index, NamespaceData ns)
569 this.TextExpressionNamespaces.Insert(index, ns.Namespace);
571 if (this.AvailableNamespaces.ContainsKey(ns.Namespace))
573 foreach (string assembly in this.AvailableNamespaces[ns.Namespace])
575 this.AddAssemblyToSet(assembly);
580 protected override void SetValueAt(int index, NamespaceData ns)
582 this.TextExpressionNamespaces[index] = ns.Namespace;
585 protected override void UpdateAssemblyInfoCore(string importedNamespace)
587 foreach (string assembly in this.AvailableNamespaces[importedNamespace])
589 this.AddAssemblyToSet(assembly);