【问题标题】:how to pass an integer as ConverterParameter?如何将整数作为 ConverterParameter 传递?
【发布时间】:2011-04-28 02:16:27
【问题描述】:

我正在尝试绑定一个整数属性:

<RadioButton Content="None"
             IsChecked="{Binding MyProperty,
                         Converter={StaticResource IntToBoolConverter},
                         ConverterParameter=0}" />

我的转换器是:

[ValueConversion(typeof(int), typeof(bool))]
public class IntToBoolConverter : IValueConverter
{
    public object Convert(object value, Type t, object parameter, CultureInfo culture)
    {
        return value.Equals(parameter);
    }

    public object ConvertBack(object value, Type t, object parameter, CultureInfo culture)
    {
        return value.Equals(false) ? DependencyProperty.UnsetValue : parameter;
    }
}

问题是当我的转换器被调用时,参数是字符串。我需要它是一个整数。我当然可以解析字符串,但我必须这样做吗?

感谢您的帮助 康斯坦丁

【问题讨论】:

  • 有谁知道如何在 Windows Phone 平台上实现这一点,我们的绑定语法略有不同? {Binding PROPERTY, Converter={StaticResource MYCONVERTER}, ConverterParameter=INT_VAL} 在此示例中 INT_VAL 将作为字符串传递

标签: wpf binding ivalueconverter


【解决方案1】:

不知道为什么WPF 的人倾向于不喜欢使用MarkupExtension。它是许多问题的完美解决方案,包括这里提到的问题。

public sealed class Int32Extension : MarkupExtension
{
    public Int32Extension(int value) { this.Value = value; }
    public int Value { get; set; }
    public override Object ProvideValue(IServiceProvider sp) { return Value; }
};

如果这个标记扩展在XAML命名空间'm'中可用,那么原始发帖人的例子变成:

<RadioButton Content="None"
             IsChecked="{Binding MyProperty,
                         Converter={StaticResource IntToBoolConverter},
                         ConverterParameter={m:Int32 0}}" />

这是可行的,因为标记扩展解析器可以看到构造函数参数的强类型并进行相应的转换,而 Binding 的 ConverterParameter 参数是(信息较少的)对象类型的。

【讨论】:

  • 谢谢,这很有用。这将是我的第一个 XAML 扩展。但我认为最好将Value 设为object 而不是int,以避免每次都在ProvideValue 中装箱。 (然后,将其设为private 以避免直接分配非法内容)。
  • @Zeus 通常ProvideValue 每个标记扩展实例只调用一次,因此装箱应该只发生一次。通过不在构造函数中执行此操作,如果从未调用过 ProvideValue,我将完全避免装箱。至于将Value 设为私有,这将排除在XAML 对象元素语法中使用标记扩展:msdn.microsoft.com/en-us/library/…
  • 你的最后一段是错误的。这称为类型转换,它也适用于属性。问题是,Binding.ConverterParameter 没有特定类型(它只是一个 object),因此解析器不知道要应用什么转换,因此每个文字都被视为字符串。
  • (所以如果你的扩展有一个默认构造函数,那么{m:Int32 Value=0} 也可以工作。)
【解决方案2】:

为了完整起见,另一种可能的解决方案(也许打字更少):

<Window
    xmlns:sys="clr-namespace:System;assembly=mscorlib" ...>
    <Window.Resources>
        <sys:Int32 x:Key="IntZero">0</sys:Int32>
    </Window.Resources>

    <RadioButton Content="None"
                 IsChecked="{Binding MyProperty,
                                     Converter={StaticResource IntToBoolConverter},
                                     ConverterParameter={StaticResource IntZero}}" />

(当然Window可以替换成UserControlIntZero可以定义得更接近实际使用的地方。)

【讨论】:

    【解决方案3】:

    给你!

    <RadioButton Content="None"
                 xmlns:sys="clr-namespace:System;assembly=mscorlib">
        <RadioButton.IsChecked>
            <Binding Path="MyProperty"
                     Converter="{StaticResource IntToBoolConverter}">
                <Binding.ConverterParameter>
                    <sys:Int32>0</sys:Int32>
                </Binding.ConverterParameter>
            </Binding>
        </RadioButton.IsChecked>
    </RadioButton>
    

    诀窍是包含基本系统类型的命名空间,然后至少以元素形式编写 ConverterParameter 绑定。

    【讨论】:

    • 这并没有改变IValueConverter.Convert()"parameter"参数的类型是object这一事实。你仍然需要转换/解析它......
    • @djacobson - 是的,但这是 ValueConversion 属性允许您指定的。不完全确定这是否真的在编译时或运行时使用。就原始海报问题而言,他指定“我需要它是一个整数。我当然可以解析字符串,但我必须这样做吗?”所以我的回答缓解了这一点,因为没有解析字符串,只有拆箱整数,我仍然更安全。
    【解决方案4】:

    在 XAML 中以某种方式表达 ConverterValue 的类型信息会很好,但我认为目前还不可能。所以我猜你必须通过一些自定义逻辑将转换器对象解析为你期望的类型。我没有看到其他方式。

    【讨论】:

      【解决方案5】:

      不要使用value.Equals。使用:

        Convert.ToInt32(value) == Convert.ToInt32(parameter)
      

      【讨论】:

      • 你为什么不想使用value.Equals
      猜你喜欢
      • 2012-04-23
      • 1970-01-01
      • 1970-01-01
      • 2010-12-25
      • 2012-03-21
      • 2017-12-15
      • 2018-03-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多