ColLayoutConverter.cs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  1. using System;
  2. using System.ComponentModel;
  3. using System.ComponentModel.Design.Serialization;
  4. using System.Globalization;
  5. using System.Security;
  6. using System.Text;
  7. using HandyControl.Tools.Extension;
  8. namespace HandyControl.Tools.Converter;
  9. public class ColLayoutConverter : TypeConverter
  10. {
  11. public override bool CanConvertFrom(ITypeDescriptorContext typeDescriptorContext, Type sourceType)
  12. {
  13. switch (Type.GetTypeCode(sourceType))
  14. {
  15. case TypeCode.Int16:
  16. case TypeCode.UInt16:
  17. case TypeCode.Int32:
  18. case TypeCode.UInt32:
  19. case TypeCode.Int64:
  20. case TypeCode.UInt64:
  21. case TypeCode.Single:
  22. case TypeCode.Double:
  23. case TypeCode.Decimal:
  24. case TypeCode.String:
  25. return true;
  26. default:
  27. return false;
  28. }
  29. }
  30. public override bool CanConvertTo(ITypeDescriptorContext typeDescriptorContext, Type destinationType) =>
  31. destinationType == typeof(InstanceDescriptor) || destinationType == typeof(string);
  32. public override object ConvertFrom(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object source)
  33. {
  34. if (source == null) throw GetConvertFromException(null);
  35. return source switch
  36. {
  37. string s => FromString(s, cultureInfo),
  38. double d => new ColLayout((int) d),
  39. _ => new ColLayout(Convert.ToInt32(source, cultureInfo))
  40. };
  41. }
  42. [SecurityCritical]
  43. public override object ConvertTo(ITypeDescriptorContext typeDescriptorContext, CultureInfo cultureInfo, object value, Type destinationType)
  44. {
  45. if (value == null) throw new ArgumentNullException(nameof(value));
  46. if (destinationType == null) throw new ArgumentNullException(nameof(destinationType));
  47. if (!(value is ColLayout th)) throw new ArgumentException("UnexpectedParameterType");
  48. if (destinationType == typeof(string)) return ToString(th, cultureInfo);
  49. if (destinationType == typeof(InstanceDescriptor))
  50. {
  51. var ci = typeof(ColLayout).GetConstructor(new[] { typeof(int), typeof(int), typeof(int), typeof(int), typeof(int), typeof(int) });
  52. return new InstanceDescriptor(ci, new object[] { th.Xs, th.Sm, th.Md, th.Lg, th.Xl, th.Xxl });
  53. }
  54. throw new ArgumentException("CannotConvertType");
  55. }
  56. private static string ToString(ColLayout th, CultureInfo cultureInfo)
  57. {
  58. var listSeparator = TokenizerHelper.GetNumericListSeparator(cultureInfo);
  59. // Initial capacity [128] is an estimate based on a sum of:
  60. // 72 = 6x double (twelve digits is generous for the range of values likely)
  61. // 4 = 4x separator characters
  62. var sb = new StringBuilder(128);
  63. sb.Append(th.Xs.ToString(cultureInfo));
  64. sb.Append(listSeparator);
  65. sb.Append(th.Sm.ToString(cultureInfo));
  66. sb.Append(listSeparator);
  67. sb.Append(th.Md.ToString(cultureInfo));
  68. sb.Append(listSeparator);
  69. sb.Append(th.Lg.ToString(cultureInfo));
  70. sb.Append(listSeparator);
  71. sb.Append(th.Xl.ToString(cultureInfo));
  72. sb.Append(listSeparator);
  73. sb.Append(th.Xxl.ToString(cultureInfo));
  74. return th.ToString();
  75. }
  76. private static ColLayout FromString(string s, CultureInfo cultureInfo)
  77. {
  78. var th = new TokenizerHelper(s, cultureInfo);
  79. var lengths = new int[6];
  80. var i = 0;
  81. while (th.NextToken())
  82. {
  83. if (i >= 6)
  84. {
  85. i = 7; // Set i to a bad value.
  86. break;
  87. }
  88. lengths[i] = th.GetCurrentToken().Value<int>();
  89. i++;
  90. }
  91. return i switch
  92. {
  93. 1 => new ColLayout(lengths[0]),
  94. 2 => new ColLayout { Xs = lengths[0], Sm = lengths[1] },
  95. 3 => new ColLayout { Xs = lengths[0], Sm = lengths[1], Md = lengths[2] },
  96. 4 => new ColLayout { Xs = lengths[0], Sm = lengths[1], Md = lengths[2], Lg = lengths[3] },
  97. 5 => new ColLayout
  98. {
  99. Xs = lengths[0],
  100. Sm = lengths[1],
  101. Md = lengths[2],
  102. Lg = lengths[3],
  103. Xl = lengths[4]
  104. },
  105. 6 => new ColLayout
  106. {
  107. Xs = lengths[0],
  108. Sm = lengths[1],
  109. Md = lengths[2],
  110. Lg = lengths[3],
  111. Xl = lengths[4],
  112. Xxl = lengths[5]
  113. },
  114. _ => throw new FormatException("InvalidStringColLayout")
  115. };
  116. }
  117. }