22// The .NET Foundation licenses this file to you under the MIT license.
33// See the LICENSE file in the project root for more information.
44
5- //
6-
7- // Allow suppression of certain presharp messages
8- #pragma warning disable 1634 , 1691
9-
10- using MS . Internal ;
11- using System ;
12- using System . ComponentModel ;
135using System . ComponentModel . Design . Serialization ;
6+ using System . Windows . Media . Animation ;
7+ using System . ComponentModel ;
148using System . Globalization ;
159using System . Reflection ;
16- using System . Windows . Media . Animation ;
17- using System . Security ;
10+ using MS . Internal ;
1811
19- using SR = MS . Internal . PresentationCore . SR ;
12+ using SR = MS . Internal . PresentationCore . SR ;
13+ using System . Runtime . CompilerServices ;
2014
2115namespace System . Windows
2216{
2317 /// <summary>
24- /// PointConverter - Converter class for converting instances of other types to Point instances
18+ /// Converter class for converting instances of <see cref="KeySpline"/> to <see cref="string"/> and vice versa.
2519 /// </summary>
2620 /// <ExternalAPI/>
2721 public class KeySplineConverter : TypeConverter
@@ -32,14 +26,7 @@ public class KeySplineConverter : TypeConverter
3226 /// <ExternalAPI/>
3327 public override bool CanConvertFrom ( ITypeDescriptorContext typeDescriptor , Type destinationType )
3428 {
35- if ( destinationType == typeof ( string ) )
36- {
37- return true ;
38- }
39- else
40- {
41- return false ;
42- }
29+ return destinationType == typeof ( string ) ;
4330 }
4431
4532 /// <summary>
@@ -51,39 +38,23 @@ public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptor, Type
5138 /// <ExternalAPI/>
5239 public override bool CanConvertTo ( ITypeDescriptorContext context , Type destinationType )
5340 {
54- if ( destinationType == typeof ( InstanceDescriptor )
55- || destinationType == typeof ( string ) )
56- {
57- return true ;
58- }
59- else
60- {
61- return false ;
62- }
41+ return destinationType == typeof ( InstanceDescriptor ) || destinationType == typeof ( string ) ;
6342 }
6443
6544 /// <summary>
6645 /// ConvertFrom
6746 /// </summary>
68- public override object ConvertFrom (
69- ITypeDescriptorContext context ,
70- CultureInfo cultureInfo ,
71- object value )
47+ public override object ConvertFrom ( ITypeDescriptorContext context , CultureInfo cultureInfo , object value )
7248 {
73- string stringValue = value as string ;
74-
75- if ( value == null )
76- {
49+ if ( value is not string stringValue )
7750 throw new NotSupportedException ( SR . Converter_ConvertFromNotSupported ) ;
78- }
7951
80- TokenizerHelper th = new TokenizerHelper ( stringValue , cultureInfo ) ;
52+ ValueTokenizerHelper tokenizer = new ( stringValue , cultureInfo ) ;
8153
82- return new KeySpline (
83- Convert . ToDouble ( th . NextTokenRequired ( ) , cultureInfo ) ,
84- Convert . ToDouble ( th . NextTokenRequired ( ) , cultureInfo ) ,
85- Convert . ToDouble ( th . NextTokenRequired ( ) , cultureInfo ) ,
86- Convert . ToDouble ( th . NextTokenRequired ( ) , cultureInfo ) ) ;
54+ return new KeySpline ( double . Parse ( tokenizer . NextTokenRequired ( ) , cultureInfo ) ,
55+ double . Parse ( tokenizer . NextTokenRequired ( ) , cultureInfo ) ,
56+ double . Parse ( tokenizer . NextTokenRequired ( ) , cultureInfo ) ,
57+ double . Parse ( tokenizer . NextTokenRequired ( ) , cultureInfo ) ) ;
8758 }
8859
8960 /// <summary>
@@ -95,47 +66,51 @@ public override object ConvertFrom(
9566 /// <param name="destinationType">Type to convert to</param>
9667 /// <returns>converted value</returns>
9768 /// <ExternalAPI/>
98- public override object ConvertTo (
99- ITypeDescriptorContext context ,
100- CultureInfo cultureInfo ,
101- object value ,
102- Type destinationType )
69+ public override object ConvertTo ( ITypeDescriptorContext context , CultureInfo cultureInfo , object value , Type destinationType )
10370 {
104- KeySpline keySpline = value as KeySpline ;
105-
106- if ( keySpline != null && destinationType != null )
71+ if ( value is KeySpline keySpline && destinationType is not null )
10772 {
73+ if ( destinationType == typeof ( string ) )
74+ return ToString ( keySpline , cultureInfo ) ;
75+
10876 if ( destinationType == typeof ( InstanceDescriptor ) )
10977 {
110- ConstructorInfo ci = typeof ( KeySpline ) . GetConstructor ( new Type [ ]
111- {
112- typeof ( double ) , typeof ( double ) ,
113- typeof ( double ) , typeof ( double )
114- } ) ;
115-
116- return new InstanceDescriptor ( ci , new object [ ]
117- {
118- keySpline . ControlPoint1 . X , keySpline . ControlPoint1 . Y ,
119- keySpline . ControlPoint2 . X , keySpline . ControlPoint2 . Y
120- } ) ;
121- }
122- else if ( destinationType == typeof ( string ) )
123- {
124- #pragma warning disable 56506 // Suppress presharp warning: Parameter 'cultureInfo.TextInfo' to this public method must be validated: A null-dereference can occur here.
125- return String . Format (
126- cultureInfo ,
127- "{0}{4}{1}{4}{2}{4}{3}" ,
128- keySpline . ControlPoint1 . X ,
129- keySpline . ControlPoint1 . Y ,
130- keySpline . ControlPoint2 . X ,
131- keySpline . ControlPoint2 . Y ,
132- cultureInfo != null ? cultureInfo . TextInfo . ListSeparator : CultureInfo . InvariantCulture . TextInfo . ListSeparator ) ;
133- #pragma warning restore 56506
78+ ConstructorInfo ci = typeof ( KeySpline ) . GetConstructor ( new Type [ ] { typeof ( double ) , typeof ( double ) , typeof ( double ) , typeof ( double ) } ) ;
79+ return new InstanceDescriptor ( ci , new object [ ] { keySpline . ControlPoint1 . X , keySpline . ControlPoint1 . Y , keySpline . ControlPoint2 . X , keySpline . ControlPoint2 . Y } ) ;
13480 }
13581 }
13682
137- // Pass unhandled cases to base class (which will throw exceptions for null value or destinationType. )
83+ // Pass unhandled cases to base class (which will throw exceptions for null value or destinationType)
13884 return base . ConvertTo ( context , cultureInfo , value , destinationType ) ;
13985 }
86+
87+ /// <summary>
88+ /// Converts <paramref name="keySpline"/> to its string representation using the specified <paramref name="cultureInfo"/>.
89+ /// </summary>
90+ /// <param name="keySpline">The <see cref="KeySpline"/> to convert to string.</param>
91+ /// <param name="cultureInfo">Culture to use when formatting doubles and choosing separator.</param>
92+ /// <returns>The formatted <paramref name="keySpline"/> as string using the specified <paramref name="cultureInfo"/>.</returns>
93+ private static string ToString ( KeySpline keySpline , CultureInfo cultureInfo )
94+ {
95+ string listSeparator = cultureInfo != null ? cultureInfo . TextInfo . ListSeparator : CultureInfo . InvariantCulture . TextInfo . ListSeparator ;
96+
97+ // Initial capacity [64] is an estimate based on a sum of:
98+ // 48 = 4x double (fourteen digits is generous for the range of values likely)
99+ // 3 = 3x separator characters
100+ // 1 = 1x scratch space for alignment
101+ DefaultInterpolatedStringHandler handler = new ( 3 , 4 , cultureInfo , stackalloc char [ 64 ] ) ;
102+ handler . AppendFormatted ( keySpline . ControlPoint1 . X ) ;
103+ handler . AppendLiteral ( listSeparator ) ;
104+
105+ handler . AppendFormatted ( keySpline . ControlPoint1 . Y ) ;
106+ handler . AppendLiteral ( listSeparator ) ;
107+
108+ handler . AppendFormatted ( keySpline . ControlPoint2 . X ) ;
109+ handler . AppendLiteral ( listSeparator ) ;
110+
111+ handler . AppendFormatted ( keySpline . ControlPoint2 . Y ) ;
112+
113+ return handler . ToStringAndClear ( ) ;
114+ }
140115 }
141116}
0 commit comments