【问题标题】:Custom FontSize should accept string literals自定义 FontSize 应该接受字符串文字
【发布时间】:2015-06-11 21:38:36
【问题描述】:

我正在尝试实现从 DatePicker 派生的自定义控件。此控件将具有 android 和 iOS 渲染器。我需要为这个控件添加 FontSize 属性,我将在渲染器类中使用它。

这是我对 FontSize 属性的实现:

public static BindableProperty FontSizeProperty = BindableProperty.Create<ExDatePicker, double>(o => o.FontSize, 16d, propertyChanged: OnFontSizeChanged);

public double FontSize
    {
        get { return (double)GetValue(FontSizeProperty); }
        set { SetValue(FontSizeProperty, value); }
    }

private static void OnFontSizeChanged(BindableObject bindable, double oldvalue, double newvalue)
    {
        var control = bindable as ExDatePicker;
        if (control != null)
        {
            control.FontSize = newvalue;
        }
    }

我需要的是能够以与原生 FontSize 属性相同的方式使用此属性,即我需要能够设置类似

FontSize="Small"

在 xaml 代码中。 有可能吗?

编辑: 在 xamarin 表单中,可以使用 FontSize="Small" 为不同平台设置设备特定的字体大小。这 autmagically 使用“小”字符串转换为双精度

Device.GetNamedSize(NamedSize.Small, typeof(ExtednedDatePicker))

我不知道如何为不在 Xamarin Forms 库中的用户创建的 FontSize 添加此自动转换

【问题讨论】:

  • 在这种情况下,您是否可以不将字体大小属性作为对象并在您的 OnFontSizeChanged 方法中尝试确定它是 string 还是 double,如果它是字符串,请使用switch statement 设置大小?
  • 将检查此解决方案
  • 在 xaml 页面中尝试这样 FontSize="{StaticResource FontSizeSmall}" 添加此资源 16
  • 我已经检查了 user1 解决方案。为了完成这项工作,我需要将属性的类型更改为对象,但它需要是双重的

标签: c# xaml xamarin font-size xamarin.forms


【解决方案1】:

我以前从未尝试过 xamarin。但我认为如果您使用带有泛型类型参数的类型转换器,这是可能的。

例如,

public class StringToDoubleTypeConverter<T> : TypeConverter where T : IConvertible
{
  // Other methods
  ...

  // Returns whether the type converter can convert an object from the specified type 
  // to the type of this converter.
  public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
  {
      return sourceType.GetInterface("IConvertible", false) != null;
  }

  // Returns whether the type converter can convert an object to the specified type.
  public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
  {
      return destinationType.GetInterface("IConvertible", false) != null;
  }

  public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
  {
      try
      {
          var convertible = (IConvertible)value;
          if (convertible != null) return convertible.ToType(typeof(T), culture);
      }
      catch (FormatException)
      {
          if (value != null && value.ToString().Equals("Small"))
          {
              return MyConstants.Small;
          }
          throw;
      }
      return null;
  }

  // Converts the specified value object to the specified type.
  public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType)
  {
      return ((IConvertible)value).ToType(destinationType, culture);
  }
}

然后在你的 FontSize 属性中使用它。

[TypeConverter(typeof(StringToDoubleTypeConverter<double>))]
public double FontSize
{
    get { return (double)GetValue(FontSizeProperty); }
    set { SetValue(FontSizeProperty, value); }
}

参考: http://www.kunal-chowdhury.com/2013/02/autotodouble-typeconverter-for-xaml-silverlight-wpdev.html

【讨论】:

    【解决方案2】:

    试试这个转换器

     public object Convert(object value, Type targetType, object parameter, string language)
            {
                return (bool)value ? "22" : "25";
            }
    

    在 xaml 页面中调用 thsi 转换器

    【讨论】:

      【解决方案3】:

      这就是在 Xamarin Forms 中使用 NamedSize 的方式。

      NamedSize 是 Enum 而不是 string。即使提供了用于在 XAML 中使用的字符串转换。

      public enum NamedSize
      {
          Default = 0,
          Micro = 1,
          Small = 2,
          Medium = 3,
          Large = 4
      }
      

      它使用Device.GetNamedSize() 从输入值中获取双精度值。 Device.GetNamedSize 使用平台服务或本机代码进行转换。

      public class FontSizeConverter : TypeConverter, IExtendedTypeConverter
      {
          object IExtendedTypeConverter.ConvertFromInvariantString(string value, IServiceProvider serviceProvider)
          {
              if (value != null)
              {
                  double size;
                  if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out size))
                      return size;
                  NamedSize namedSize;
                  if (Enum.TryParse(value, out namedSize))
                  {
                      Type type;
                      var valueTargetProvider = serviceProvider.GetService(typeof(IProvideValueTarget)) as IProvideValueTarget;
                      type = valueTargetProvider != null ? valueTargetProvider.TargetObject.GetType() : typeof(Label);
                      return Device.GetNamedSize(namedSize, type, false);
                  }
              }
              throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", value, typeof(double)));
          }
      
          public override object ConvertFromInvariantString(string value)
          {
              if (value != null)
              {
                  double size;
                  if (double.TryParse(value, NumberStyles.Number, CultureInfo.InvariantCulture, out size))
                      return size;
                  NamedSize namedSize;
                  if (Enum.TryParse(value, out namedSize))
                      return Device.GetNamedSize(namedSize, typeof(Label), false);
              }
              throw new InvalidOperationException(string.Format("Cannot convert \"{0}\" into {1}", value, typeof(double)));
          }
      }
      

      【讨论】:

        猜你喜欢
        • 2012-07-19
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-09-05
        • 2021-08-21
        • 2012-01-16
        • 1970-01-01
        相关资源
        最近更新 更多