如何通过 ConverterParameter 将 TimeSpan.FromSeconds 传递给转换器?
How can I pass TimeSpan.FromSeconds to a converter via the ConverterParameter?
鉴于以下情况:
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
,但我希望有更灵活的东西。
那么我正在尝试做的事情可行吗?我怎样才能正确地做到这一点?
解决方案
感谢一位乐于助人的评论者,错误出在执行中。显然,您不能隐式地将方法或函数名称作为参数传递(至少不能在 from XAML 中传递)。
为了避免这种情况,我更改了转换器代码以将 TimeSpan.FromFOO
函数公开为 Func<double,TimeSpan>
属性,以便它们可以传递给 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 -
<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 传递的实例。
鉴于以下情况:
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
,但我希望有更灵活的东西。
那么我正在尝试做的事情可行吗?我怎样才能正确地做到这一点?
解决方案
感谢一位乐于助人的评论者,错误出在执行中。显然,您不能隐式地将方法或函数名称作为参数传递(至少不能在 from XAML 中传递)。
为了避免这种情况,我更改了转换器代码以将 TimeSpan.FromFOO
函数公开为 Func<double,TimeSpan>
属性,以便它们可以传递给 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 -
<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 传递的实例。