使用 x:Bind 时指定签名

Specify signature when using x:Bind

UWP 允许您绑定到静态方法。我正在尝试使用

获取时间字符串
<TextBlock Text={x:Bind MyDateTime.ToString(MyPatternString)} />

其中 MyPatternString 是 "h:mm tt"。

问题是 DateTimeToString() 方法有几个不同的签名。第一个收到 IFormatProvider。因此,我收到构建错误:

Function parameter 'provider' is invalid or missmatched

有什么方法可以告诉它我希望使用接受字符串的签名吗?我还以为它会自动知道这一点。

您需要使用 IValueConverter 来格式化显示的文本。创建一个继承自 IValueConverter 的 class。

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

您只需将一个方法添加到您的 ViewModel 并使用它即可!

这样你的绑定表达式就可以改成这样:

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

请注意,这仅适用于 Windows 10 周年更新!关于此事的更多信息 here!

自己搜索答案后找到你的问题;在任何地方都找不到太多帮助,但经过反复试验后确实弄明白了。

Function parameter 'provider' is invalid or mismatched

在 XAML 中调用特定重载的原因是 DateTimeProperty.ToString(string, IFormatProvider).

在我的例子中,我显示的任何值都在用户控件中,因此我为每个值添加了一个 CultureInfo 依赖项 属性 并将其绑定到我的视图模型上的公共源。

如果是 C#,添加:

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} />