[corlib] Update ValueTuple implementation
[mono.git] / mcs / class / referencesource / System.Activities.Presentation / System.Activities.Presentation / System / Activities / Presentation / Base / Core / Internal / PropertyEditing / Editors / PropertyValueToStandardValuesConverter.cs
1 //----------------------------------------------------------------
2 // Copyright (c) Microsoft Corporation.  All rights reserved.
3 //----------------------------------------------------------------
4 namespace System.Activities.Presentation.Internal.PropertyEditing.Editors 
5 {
6     using System;
7     using System.Collections;
8     using System.ComponentModel;
9     using System.Diagnostics;
10     using System.Diagnostics.CodeAnalysis;
11     using System.Globalization;
12     using System.Windows.Data;
13
14     using System.Runtime;
15     using System.Activities.Presentation;
16     using System.Activities.Presentation.PropertyEditing;
17     using System.Activities.Presentation.Internal.Properties;
18     using System.Activities.Presentation.Internal.PropertyEditing.Model;
19
20     // <summary>
21     // Retrieves StandardValues from a passed in PropertyValue, making sure that if a TypeConverter
22     // exists and if it supports ConvertToString() method, it will be called on each value contained
23     // in the StandardValues collection.
24     // This class is instantiated through XAML
25     // </summary>
26     [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses")]
27     internal class PropertyValueToStandardValuesConverter : IValueConverter 
28     {
29         // IValueConverter Members
30
31         public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
32         {
33
34             Fx.Assert(typeof(IEnumerable).IsAssignableFrom(targetType), "Expecting IEnumerable as the targetType");
35
36             PropertyValue propertyValue = value as PropertyValue;
37             if (propertyValue == null)
38             {
39                 return null;
40             }
41
42             ModelPropertyEntryBase parentProperty = (ModelPropertyEntryBase)propertyValue.ParentProperty;
43             return new ConvertedStandardValuesCollection(parentProperty, culture);
44         }
45
46         public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
47         {
48             throw FxTrace.Exception.AsError(new InvalidOperationException());
49         }
50
51
52         // <summary>
53         // An implementation of ICollection that defers access to the standard
54         // values collection.  Accessing the StandardValues collection may be
55         // expensive, so we defer it until we absolutely need it.
56         // </summary>
57         private class ConvertedStandardValuesCollection : ICollection 
58         {
59
60             private ModelPropertyEntryBase _property;
61             private CultureInfo _culture;
62             private ICollection _contents;
63
64             internal ConvertedStandardValuesCollection(ModelPropertyEntryBase property, CultureInfo culture) 
65             {
66                 _property = property;
67                 _culture = culture;
68             }
69
70             public int Count 
71             {
72                 get { return Contents.Count; }
73             }
74
75             public bool IsSynchronized 
76             {
77                 get { return false; }
78             }
79
80             public object SyncRoot 
81             {
82                 get { return Contents.SyncRoot; }
83             }
84
85         // IEnumerable Members
86
87             private ICollection Contents 
88             {
89                 get {
90                     if (_contents == null) 
91                     {
92                         ICollection standardValues = _property.StandardValues;
93                         TypeConverter converter = _property.Converter;
94
95                         if (standardValues != null && (converter == null || !converter.CanConvertTo(typeof(string)))) 
96                         {
97                             _contents = standardValues;
98                         }
99                         else 
100                         {
101                             ArrayList convertedStandardValues = new ArrayList(standardValues == null ? 0 : standardValues.Count);
102                             if (standardValues != null) 
103                             {
104                                 foreach (object standardValue in standardValues) 
105                                 {
106                                     convertedStandardValues.Add(converter.ConvertToString(null, _culture, standardValue));
107                                 }
108                             }
109                             _contents = convertedStandardValues;
110                         }
111
112                         // PS 107537: Special-case handling for nullable enum types
113                         if (EditorUtilities.IsNullableEnumType(_property.PropertyType))
114                         {
115                             ArrayList filteredStandardValues = new ArrayList();
116                             filteredStandardValues.Add(EditorUtilities.NullString);
117                             foreach (var i in (ArrayList)_contents)
118                             {
119                                 if (i != null)
120                                 {
121                                     filteredStandardValues.Add(i);
122                                 }
123                             }
124                             _contents = filteredStandardValues;
125                         }
126                     }
127
128                     return _contents;
129                 }
130             }
131
132         // ICollection Members
133
134             public void CopyTo(Array array, int index) 
135             {
136                 Contents.CopyTo(array, index);
137             }
138
139             public IEnumerator GetEnumerator() 
140             {
141                 return Contents.GetEnumerator();
142             }
143
144         }
145     }
146 }