Укажите подпись при использовании x:Bind

UWP позволяет выполнять привязку к статическому методу. Я пытаюсь получить строку времени, используя

<TextBlock Text={x:Bind MyDateTime.ToString(MyPatternString)} />

где MyPatternString это "ч:мм тт".

Проблема в том, что метод ToString() DateTime имеет несколько разных сигнатур. Первый получает IFormatProvider. Из-за этого я получаю ошибку сборки:

Параметр функции "поставщик" недействителен или не соответствует

Есть ли способ сказать, что я хочу использовать подпись, которая принимает строку? Я бы подумал, что он автоматически узнает об этом.


person RareNCool    schedule 20.02.2017    source источник
comment
Разве вы не можете просто вставить IFormatProvider (например, CultureInfo.Invariant или около того)? В противном случае создайте свой собственный метод преобразования для вызова.   -  person Henk Holterman    schedule 21.02.2017


Ответы (3)


Вы можете просто добавить метод в свою ViewModel и использовать его вместо этого!

Таким образом, ваше выражение привязки можно изменить на это:

<TextBlock Text={x:Bind FormatDateToString(MyDateTime)} />

Имейте в виду, что это работает только с юбилейным обновлением Windows 10! Дополнительная информация по этому вопросу здесь!

person Pedro Lamas    schedule 21.02.2017
comment
Хм. Похоже, это самое близкое, что я могу получить. Это все еще кажется неуклюжим, но это лучше, чем ничего. - person RareNCool; 21.02.2017

Нашел ваш вопрос после поиска ответа самостоятельно; нигде не нашел много помощи, но понял это после проб и ошибок.

Параметр функции "поставщик" недействителен или не соответствует

Причина этого в том, что в XAML вызывается конкретная перегрузка DateTimeProperty.ToString(string, IFormatProvider).

В моем случае любое значение, которое я отображаю, находится в пользовательском элементе управления, поэтому для каждого я добавил свойство зависимости CultureInfo и привязал его к общему источнику в моей модели представления.

Если С#, добавьте:

using System.Globalization;

затем

public static readonly DependencyProperty CultureInfoProperty = DependencyProperty.Register(
        "CultureInfo", typeof(CultureInfo), typeof(XyzReadoutView), new PropertyMetadata(default(CultureInfo)));

    public CultureInfo CultureInfo
    {
        get { return (CultureInfo) GetValue(CultureInfoProperty); }
        set { SetValue(CultureInfoProperty, value); }
    }

Это создает локальный экземпляр, необходимый для x:Bind, ошибки компиляции возникают при использовании статического свойства.

И XAML:

<TextBlock Text={x:Bind MyDateTime.ToString('h:mm tt', CultureInfo)} />

Обратите внимание, что формат окружен ', а не ".

Кроме того, это будет обновляться только один раз, так как режим для x: Bind по умолчанию имеет значение Mode=OneTime; если вы хотите, чтобы изменения в DateTime или CultureInfo распространялись, режим необходимо изменить на Mode=OneWay.

<TextBlock Text={x:Bind MyDateTime.ToString('h:mm tt', CultureInfo), Mode=OneWay} />

Если формат может изменяться пользователем, я бы также создал для него свойство зависимости для обновлений и простой привязки управления к модели представления, но это только мои личные предпочтения.

public static readonly DependencyProperty DateTimeFormatProperty = DependencyProperty.Register(
        "DateTimeFormat", typeof(string), typeof(XyzReadoutView), new PropertyMetadata(default(string)));

    public string DateTimeFormat
    {
        get { return (string) GetValue(DateTimeFormatProperty); }
        set { SetValue(DateTimeFormatProperty, value); }
    }

И XAML:

<TextBlock Text={x:Bind MyDateTime.ToString(DateTimeFormat, CultureInfo), Mode=OneWay} />
person Joel Janssen    schedule 16.01.2018

Вам нужно использовать IValueConverter для форматирования текста для отображения. Создайте класс, который наследуется от IValueConverter.

public class DateFormatter : IValueConverter
{
    // This converts the DateTime object to the string to display.
    public object Convert(object value, Type targetType, 
        object parameter, string language)
    {
        // Retrieve the format string and use it to format the value.
        string formatString = parameter as string;
        if (!string.IsNullOrEmpty(formatString))
        {
            return string.Format(
                new CultureInfo(language), formatString, value);
        }
        // If the format string is null or empty, simply call ToString()
        // on the value.
        return value.ToString();
    }

    // No need to implement converting back on a one-way binding 
    public object ConvertBack(object value, Type targetType, 
        object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

Зарегистрируйте его как ресурс на странице, а затем вы можете указать конвертер в привязке

<TextBlock Text={x:Bind MyDateTime, Converter={StaticResource DateFormatConverter}}, ConverterParameter="mm/dd/yyyy"}"/>

https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Data.IValueConverter

person Ken Tucker    schedule 20.02.2017
comment
Я знаю, как использовать конвертер для выполнения того, что я пытаюсь сделать. Мой вопрос скорее из любопытства. Кажется, должен быть способ указать подпись. - person RareNCool; 20.02.2017
comment
Избегать конвертеров — одна из целей x:Bind. - person Henk Holterman; 21.02.2017