【问题标题】:How can I pass TimeSpan.FromSeconds to a converter via the ConverterParameter?如何通过 ConverterParameter 将 TimeSpan.FromSeconds 传递给转换器?
【发布时间】:2018-03-23 06:07:19
【问题描述】:

鉴于以下情况:

namespace Foo.Converters {
    public class TimespanConverter : IValueConverter {
        public object Convert( object value, Type targetType, object parameter, CultureInfo culture ) =>
            ( parameter as Func<double, TimeSpan> )?.Invoke( ( double )( value ) );
        public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture ) =>
            throw new NotImplementedException( );
    }
}

如何将TimeSpan.FromSeconds 传递给ConverterParameter

我尝试了以下方法,但没有成功 -

<Window
    x:Class="Foo.MyWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:c="clr-namespace:Foo.Converters"
    xmlns:lib="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:Foo"
    mc:Ignorable="d" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <c:TimespanConverter x:Key="TSC" />
    </Window.Resources>
    <Viewbox>
        <TextBlock Text="{Binding
            Seconds, Source={x:Static Application.Current},
            Converter={StaticResource TSC},
            ConverterParameter={x:Static lib:TimeSpan.FromSeconds}}" />
    </Viewbox>
</Window>

我在设计器中遇到错误 - The member "FromSeconds" is not recognized or is not accessible。我检查了 TimeSpan 结构,它包含在 System 命名空间中(在 mscorlib 程序集下),并且我过去曾无数次使用 .FromFOO 进行转换(只是不是以这种方式)。

我知道我可以直接在转换器中调用TimeSpan.FromSeconds,但我希望有更灵活的东西。

那么我正在尝试做的事情可能吗?我怎样才能正确地做到这一点?

【问题讨论】:

  • TimeSpan.FromSeconds 是一种方法,绝对不是一个函数。只需传入一个字符串,您的转换器将switch 继续前进。
  • Tch。好的。不理想,而且绝对不是我想要的,但我认为更雄辩的解决方法是将 TimeSpan.FromFOO 方法从转换器本身公开为 Funcs,并将它们作为转换器参数传递。
  • 好吧,其他威尔,您可以随时自己创建。创建一个静态类型,该类型公开您可以在静态绑定中使用的属性,该绑定将与您的值转换器一起使用...
  • 是的,通常当我自言自语时,我是唯一参与对话的人。见编辑。
  • 我认为您应该将其作为解决方案发布而不是编辑,因为它解决方案,并且很高兴有记录。

标签: c# wpf xaml converter func


【解决方案1】:

解决方案

感谢一位乐于助人的评论者,错误出在实施中。显然,您不能将方法或函数名称作为参数隐式传递(至少,不是来自 XAML)。

为了避免这种情况,我更改了转换器代码以将 TimeSpan.FromFOO 函数公开为 Func&lt;double,TimeSpan&gt; 属性,以便它们可以传递给 ConverterParameter -

namespace Foo.Converters {
    public class TimespanConverter : IValueConverter {
        public static Func<double, TimeSpan> FromMilliseconds => TimeSpan.FromMilliseconds;
        public static Func<double, TimeSpan> FromSeconds => TimeSpan.FromSeconds;
        public static Func<double, TimeSpan> FromMinutes => TimeSpan.FromMinutes;
        public static Func<double, TimeSpan> FromHours => TimeSpan.FromHours;
        public static Func<double, TimeSpan> FromDays => TimeSpan.FromDays;

        public object Convert(
            object value, Type targetType, object parameter, CultureInfo culture ) =>
            ( parameter as Func<double, TimeSpan> )?.Invoke( ( double )( value ) );
        public object ConvertBack(
            object value, Type targetType, object parameter, CultureInfo culture ) =>
            throw new NotImplementedException( );
    }
}

还有窗户——

<Window
    x:Class="Foo.MyWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:c="clr-namespace:Foo.Converters"
    xmlns:lib="clr-namespace:System;assembly=mscorlib"
    xmlns:local="clr-namespace:Foo"
    mc:Ignorable="d" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <c:TimespanConverter x:Key="TSC" />
    </Window.Resources>
    <Viewbox>
        <TextBlock Text="{Binding
            Seconds, Source={x:Static Application.Current},
            Converter={StaticResource TSC},
            ConverterParameter={x:Static c:TimespanConverter.FromSeconds}}" />
    </Viewbox>
</Window>

设计时错误已消失,但文本仍未显示。我不太担心实际显示的文本和实现它的最佳方法,这似乎是目前最好的选择。此外,它可以扩展到任何希望将 Func 作为 ConverterParameter 传递的实例。

【讨论】:

  • Application.Current 没有名为 Seconds 的属性,我猜这就是为什么没有显示文本的原因。检查您的输出是否存在绑定错误。我不确定您希望从哪里获得此 Seconds 值,但它不会存在。
  • 如果我添加了该属性,它会这样做。我没有发布该代码,因为我希望有些事情是隐含的。
猜你喜欢
  • 2012-03-21
  • 1970-01-01
  • 2012-04-23
  • 2011-04-28
  • 2017-12-15
  • 1970-01-01
  • 1970-01-01
  • 2023-03-06
  • 2013-09-22
相关资源
最近更新 更多