自定义FontSize应接受字符串文字

时间:2015-04-07 10:12:08

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

我正在尝试实现从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”为不同平台设置设备特定的字体大小。这会使用

自动将“Small”字符串转换为double
Device.GetNamedSize(NamedSize.Small, typeof(ExtednedDatePicker))

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

3 个答案:

答案 0 :(得分:1)

这是Xamarin Forms中NamedSize的完成方式。

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

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

它使用Device.GetNamedSize()从输入值中获取double值。 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)));
    }
}

答案 1 :(得分:0)

试试这个转换器

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

在xaml页面中调用thsi转换器

答案 2 :(得分:-3)

我之前从未尝试过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