Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
Chained.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 using System;
4 using System.Globalization;
5 using System.Windows.Data;
6 using System.Windows.Markup;
7 
8 namespace SiliconStudio.Presentation.ValueConverters
9 {
10  /// <summary>
11  /// This converter can chain up to <see cref="MaxConverterCount"/> <see cref="IValueConverter"/> to convert a value. The first converter takes
12  /// the value parameter of the Chained value converter itself, and then each converter takes the previous converter output as input value.
13  /// The parameter and target type of each converter can also be specified. <see cref="IValueConverter.ConvertBack"/> is supported and converters are invoked backward.
14  /// </summary>
15  /// <remarks>This converter is also a <see cref="MarkupExtension"/>, which makes it convenient to use in XAML.</remarks>
17  {
18  /// <summary>
19  /// The maximum number of converters that can be chained
20  /// </summary>
21  public const int MaxConverterCount = 8;
22 
23  /// <summary>
24  /// Initializes a new instance of the <see cref="Chained"/> class.
25  /// </summary>
26  public Chained()
27  : this(null, null, null, null, null, null, null, null)
28  {
29  }
30 
31  /// <summary>
32  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
33  /// </summary>
34  /// <param name="converter">The first value converter.</param>
35  public Chained(IValueConverter converter)
36  : this(converter, null, null, null, null, null, null, null)
37  {
38  }
39 
40  /// <summary>
41  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
42  /// </summary>
43  /// <param name="converter1">The first value converter.</param>
44  /// <param name="converter2">The second value converter.</param>
45  public Chained(IValueConverter converter1, IValueConverter converter2)
46  : this(converter1, converter2, null, null, null, null, null, null)
47  {
48  }
49 
50  /// <summary>
51  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
52  /// </summary>
53  /// <param name="converter1">The first value converter.</param>
54  /// <param name="converter2">The second value converter.</param>
55  /// <param name="converter3">The third value converter.</param>
56  public Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3)
57  : this(converter1, converter2, converter3, null, null, null, null, null)
58  {
59  }
60 
61  /// <summary>
62  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
63  /// </summary>
64  /// <param name="converter1">The first value converter.</param>
65  /// <param name="converter2">The second value converter.</param>
66  /// <param name="converter3">The third value converter.</param>
67  /// <param name="converter4">The fourth value converter.</param>
68  public Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4)
69  : this(converter1, converter2, converter3, converter4, null, null, null, null)
70  {
71  }
72 
73  /// <summary>
74  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
75  /// </summary>
76  /// <param name="converter1">The first value converter.</param>
77  /// <param name="converter2">The second value converter.</param>
78  /// <param name="converter3">The third value converter.</param>
79  /// <param name="converter4">The fourth value converter.</param>
80  /// <param name="converter5">The fifth value converter.</param>
81  public Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4,
82  IValueConverter converter5)
83  : this(converter1, converter2, converter3, converter4, converter5, null, null, null)
84  {
85  }
86 
87  /// <summary>
88  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
89  /// </summary>
90  /// <param name="converter1">The first value converter.</param>
91  /// <param name="converter2">The second value converter.</param>
92  /// <param name="converter3">The third value converter.</param>
93  /// <param name="converter4">The fourth value converter.</param>
94  /// <param name="converter5">The fifth value converter.</param>
95  /// <param name="converter6">The sixth value converter.</param>
96  public Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4,
97  IValueConverter converter5, IValueConverter converter6)
98  : this(converter1, converter2, converter3, converter4, converter5, converter6, null, null)
99  {
100  }
101 
102  /// <summary>
103  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
104  /// </summary>
105  /// <param name="converter1">The first value converter.</param>
106  /// <param name="converter2">The second value converter.</param>
107  /// <param name="converter3">The third value converter.</param>
108  /// <param name="converter4">The fourth value converter.</param>
109  /// <param name="converter5">The fifth value converter.</param>
110  /// <param name="converter6">The sixth value converter.</param>
111  /// <param name="converter7">The seventh value converter.</param>
112  public Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4,
113  IValueConverter converter5, IValueConverter converter6, IValueConverter converter7)
114  : this(converter1, converter2, converter3, converter4, converter5, converter6, converter7, null)
115  {
116  }
117 
118  /// <summary>
119  /// Initializes a new instance of the <see cref="Chained"/> class with the given instances of <see cref="IValueConverter"/>.
120  /// </summary>
121  /// <param name="converter1">The first value converter.</param>
122  /// <param name="converter2">The second value converter.</param>
123  /// <param name="converter3">The third value converter.</param>
124  /// <param name="converter4">The fourth value converter.</param>
125  /// <param name="converter5">The fifth value converter.</param>
126  /// <param name="converter6">The sixth value converter.</param>
127  /// <param name="converter7">The seventh value converter.</param>
128  /// <param name="converter8">The eighth value converter.</param>
129  public Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4,
130  IValueConverter converter5, IValueConverter converter6, IValueConverter converter7, IValueConverter converter8)
131  {
132  Converter1 = converter1;
133  Converter2 = converter2;
134  Converter3 = converter3;
135  Converter4 = converter4;
136  Converter5 = converter5;
137  Converter6 = converter6;
138  Converter7 = converter7;
139  Converter8 = converter8;
140  }
141 
142  /// <summary>
143  /// Gets or sets the first converter to chain.
144  /// </summary>
145  public IValueConverter Converter1 { get { return converters[0]; } set { converters[0] = value; } }
146  /// <summary>
147  /// Gets or sets the second converter to chain.
148  /// </summary>
149  public IValueConverter Converter2 { get { return converters[1]; } set { converters[1] = value; } }
150  /// <summary>
151  /// Gets or sets the third converter to chain.
152  /// </summary>
153  public IValueConverter Converter3 { get { return converters[2]; } set { converters[2] = value; } }
154  /// <summary>
155  /// Gets or sets the fourth converter to chain.
156  /// </summary>
157  public IValueConverter Converter4 { get { return converters[3]; } set { converters[3] = value; } }
158  /// <summary>
159  /// Gets or sets the fifth converter to chain.
160  /// </summary>
161  public IValueConverter Converter5 { get { return converters[4]; } set { converters[4] = value; } }
162  /// <summary>
163  /// Gets or sets the sixth converter to chain.
164  /// </summary>
165  public IValueConverter Converter6 { get { return converters[5]; } set { converters[5] = value; } }
166  /// <summary>
167  /// Gets or sets the seventh converter to chain.
168  /// </summary>
169  public IValueConverter Converter7 { get { return converters[6]; } set { converters[6] = value; } }
170  /// <summary>
171  /// Gets or sets the eighth converter to chain.
172  /// </summary>
173  public IValueConverter Converter8 { get { return converters[7]; } set { converters[7] = value; } }
174 
175  /// <summary>
176  /// Gets or sets the parameter of the first converter to chain.
177  /// </summary>
178  public object Parameter1 { get { return converterParameters[0]; } set { converterParameters[0] = value; } }
179  /// <summary>
180  /// Gets or sets the parameter of the second converter to chain.
181  /// </summary>
182  public object Parameter2 { get { return converterParameters[1]; } set { converterParameters[1] = value; } }
183  /// <summary>
184  /// Gets or sets the parameter of the third converter to chain.
185  /// </summary>
186  public object Parameter3 { get { return converterParameters[2]; } set { converterParameters[2] = value; } }
187  /// <summary>
188  /// Gets or sets the parameter of the fourth converter to chain.
189  /// </summary>
190  public object Parameter4 { get { return converterParameters[3]; } set { converterParameters[3] = value; } }
191  /// <summary>
192  /// Gets or sets the parameter of the fifth converter to chain.
193  /// </summary>
194  public object Parameter5 { get { return converterParameters[4]; } set { converterParameters[4] = value; } }
195  /// <summary>
196  /// Gets or sets the parameter of the sixth converter to chain.
197  /// </summary>
198  public object Parameter6 { get { return converterParameters[5]; } set { converterParameters[5] = value; } }
199  /// <summary>
200  /// Gets or sets the parameter of the seventh converter to chain.
201  /// </summary>
202  public object Parameter7 { get { return converterParameters[6]; } set { converterParameters[6] = value; } }
203  /// <summary>
204  /// Gets or sets the parameter of the eighth converter to chain.
205  /// </summary>
206  public object Parameter8 { get { return converterParameters[7]; } set { converterParameters[7] = value; } }
207 
208  /// <summary>
209  /// Gets or sets the target type of the first converter to chain.
210  /// </summary>
211  public Type TargetType1 { get { return converterTargetType[0]; } set { converterTargetType[0] = value; } }
212  /// <summary>
213  /// Gets or sets the target type of the second converter to chain.
214  /// </summary>
215  public Type TargetType2 { get { return converterTargetType[1]; } set { converterTargetType[1] = value; } }
216  /// <summary>
217  /// Gets or sets the target type of the third converter to chain.
218  /// </summary>
219  public Type TargetType3 { get { return converterTargetType[2]; } set { converterTargetType[2] = value; } }
220  /// <summary>
221  /// Gets or sets the target type of the fourth converter to chain.
222  /// </summary>
223  public Type TargetType4 { get { return converterTargetType[3]; } set { converterTargetType[3] = value; } }
224  /// <summary>
225  /// Gets or sets the target type of the fifth converter to chain.
226  /// </summary>
227  public Type TargetType5 { get { return converterTargetType[4]; } set { converterTargetType[4] = value; } }
228  /// <summary>
229  /// Gets or sets the target type of the sixth converter to chain.
230  /// </summary>
231  public Type TargetType6 { get { return converterTargetType[5]; } set { converterTargetType[5] = value; } }
232  /// <summary>
233  /// Gets or sets the target type of the seventh converter to chain.
234  /// </summary>
235  public Type TargetType7 { get { return converterTargetType[6]; } set { converterTargetType[6] = value; } }
236  /// <summary>
237  /// Gets or sets the target type of the eighth converter to chain.
238  /// </summary>
239  public Type TargetType8 { get { return converterTargetType[7]; } set { converterTargetType[7] = value; } }
240 
241  private readonly IValueConverter[] converters = new IValueConverter[MaxConverterCount];
242  private readonly object[] converterParameters = new object[MaxConverterCount];
243  private readonly Type[] converterTargetType = new Type[MaxConverterCount];
244 
245  /// <inheritdoc/>
246  public override object ProvideValue(IServiceProvider serviceProvider)
247  {
248  return this;
249  }
250 
251  /// <inheritdoc/>
252  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
253  {
254  object output = value;
255  bool conversionEnded = false;
256 
257  for (int i = 0; i < MaxConverterCount; ++i)
258  {
259  object input = output;
260  if (converters[i] == null)
261  {
262  conversionEnded = true;
263  continue;
264  }
265 
266  if (conversionEnded)
267  throw new InvalidOperationException(string.Format("Converter{0} is not null but previous Converter{1} was null", i, i - 1));
268 
269  output = converters[i].Convert(input, converterTargetType[i] ?? typeof(object), converterParameters[i], culture);
270  }
271  return output;
272  }
273 
274  /// <inheritdoc/>
275  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
276  {
277  object output = value;
278 
279  bool conversionStarted = false;
280 
281  for (int i = MaxConverterCount - 1; i >= 0; --i)
282  {
283  object input = output;
284  if (converters[i] == null)
285  {
286  if (!conversionStarted)
287  continue;
288  throw new InvalidOperationException(string.Format("Converter{0} is null but following Converter{1} is not null", i, i + 1));
289  }
290 
291  conversionStarted = true;
292 
293  output = converters[i].Convert(input, converterTargetType[i] ?? typeof(object), converterParameters[i], culture);
294  }
295  return output;
296  }
297  }
298 }
Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4, IValueConverter converter5, IValueConverter converter6)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:96
Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:68
object Convert(object value, Type targetType, object parameter, CultureInfo culture)
Definition: Chained.cs:252
Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4, IValueConverter converter5, IValueConverter converter6, IValueConverter converter7, IValueConverter converter8)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:129
Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4, IValueConverter converter5, IValueConverter converter6, IValueConverter converter7)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:112
Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:56
Chained(IValueConverter converter1, IValueConverter converter2, IValueConverter converter3, IValueConverter converter4, IValueConverter converter5)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:81
override object ProvideValue(IServiceProvider serviceProvider)
Definition: Chained.cs:246
Chained(IValueConverter converter1, IValueConverter converter2)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:45
Chained(IValueConverter converter)
Initializes a new instance of the Chained class with the given instances of IValueConverter.
Definition: Chained.cs:35
object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
Definition: Chained.cs:275
Chained()
Initializes a new instance of the Chained class.
Definition: Chained.cs:26
This converter can chain up to MaxConverterCount IValueConverter to convert a value. The first converter takes the value parameter of the Chained value converter itself, and then each converter takes the previous converter output as input value. The parameter and target type of each converter can also be specified. IValueConverter.ConvertBack is supported and converters are invoked backward.
Definition: Chained.cs:16