Как использовать расширение разметки XAML для преобразования даты-времени в строку?

#xaml #xamarin #xamarin.forms

Вопрос:

Я создал расширение разметки для преобразования даты-времени в строку

 public class DateTimeConverterExtension : IMarkupExtension<string> {
    public DateTime Source { get; set; }
    public string ProvideValue(IServiceProvider serviceProvider) {
        var delta = DateTime.Now -Source;
        if (delta.TotalDays > 0) {
            return string.Format(StringResources.DaysAgo, delta.TotalDays);
        }
        if (delta.TotalHours > 0) {
            return string.Format(StringResources.HoursAgo, delta.TotalHours);
        }
        if (delta.TotalMinutes > 0) {
            return string.Format(StringResources.MinutesAgo, delta.TotalMinutes);
        }
        return string.Format(StringResources.MinutesAgo, 0);
    }

    object IMarkupExtension.ProvideValue(IServiceProvider serviceProvider) {
        return (this as IMarkupExtension<string>).ProvideValue(serviceProvider);
    }
}
 

Но когда я использую это в XAML:

 <Label Text="{markupExtensions:DateTimeConverter Source={Binding Time}}" />
 

Я получаю следующую ошибку:

Для «Источника» не найдено никакого свойства, свойства BindableProperty или события или несоответствия типа между значением и свойством.

Где я ошибся?

Комментарии:

1. это звучит так, как будто это должен быть преобразователь значений

2. Вы правы, спасибо. Это решило мою проблему. Я все еще удивляюсь, почему мой пример не работает.

3. Возможно, произошла ошибка при вызове InitializeComponent в конструкторе ДО того, как был установлен BindingContext. Функция MarkupExtension запустилась, но не смогла найти действительный источник. Напротив, ValueConverter является ЧАСТЬЮ выражения привязки; он не будет вызываться до тех пор, пока не появится BindingContext. Я думаю, что единственные привязки, которые вы увидите с наценками, — это привязки к x:Static значениям.

Ответ №1:

Вы можете конвертировать дату и время с помощью конвертера.

Для работы с конвертером вам необходимо создать класс, реализующий интерфейс IValueConverter

код, подобный:

 public class DatetimeToStringConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null)
            return string.Empty;

        var datetime = (DateTime)value;
        //put your custom formatting here
        return datetime.ToLocalTime().ToString("g");
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException(); 
    }
}
 

затем используйте его в xaml:

 <ResourceDictionary>
    <local:DatetimeToStringConverter x:Key="cnvDateTimeConverter"></local:DatetimeToStringConverter>
</ResourceDictionary>
...
<Label Text="{Binding Date, Converter={StaticResource cnvDateTimeConverter}}"></Label>