由于目标类型,在WPF中链接IValueConvertes的问题

时间:2015-08-25 04:12:29

标签: wpf ivalueconverter

我试图将转换器作为Town的回答链接到Is there a way to chain multiple value converters in XAML?

我还希望通过targetType检查来使单个转换器更严格: -

if (targetType != typeof(bool))
        throw new InvalidOperationException("The target must be a     
boolean");

但是链条失败,因为最终目标类型与每个阶段的目标不同。

我可以删除类型检查以使其不那么严格,如SO中的大多数示例所示,但我更喜欢链接,它也考虑每个转换器的类型检查。例如。为了更好的单元测试等。

界面IValueConverter也没有暴露目标类型,我发现很难自己添加检查。

 public class InverseBooleanConverter : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
        if (targetType != typeof(bool))
            throw new InvalidOperationException("The target must be a boolean");

        if (!(value is bool))
            throw new ArgumentException("Argument 'value' must be of type bool");

        return !(bool)value;
        }
         ....
     }

[ValueConversion(typeof(bool), typeof(Visibility))]
public class VisibilityFromBoolConverter : IValueConverter
    {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
        if (targetType != typeof(Visibility))
            throw new InvalidOperationException("The target must be a Visibility");

        if (!(value is bool))
            throw new ArgumentException("Argument 'value' must be of type bool");

        var isVisible = (bool)value;
        return isVisible ? Visibility.Visible : Visibility.Collapsed;
        }
        ....
     }

复合材料就像: -

            <Converters:ValueConverterGroup x:Key="InvertAndVisible">
                  <Converters:InverseBooleanConverter />
                  <Converters:VisibilityFromBoolConverter />
            </Converters:ValueConverterGroup>

但我从InverseBooleanConverter获得异常“目标必须是布尔值”,因为它期望目标是bool而不是Visibility(链的最终目标)。

1 个答案:

答案 0 :(得分:0)

原始的ValueConverterGroup代码将最终的targetType传递到每个阶段,这就是您的检查失败的原因。您需要做的就是修改该行为以传递下一个转换器targetType:

[ValueConversion(typeof(bool), typeof(Visibility))]
public class ValueConverterGroup : List<IValueConverter>, IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        for (int i = 0; i < this.Count(); i++)
        {
            var targ = (i == this.Count() - 1) 
                ? targetType 
                : (this[i + 1].GetType().GetCustomAttributes(typeof(ValueConversionAttribute), false).First() as ValueConversionAttribute).SourceType;
            value = this[i].Convert(value, targ, parameter, culture);
        }
        if (value.GetType() != (this.GetType().GetCustomAttributes(typeof(ValueConversionAttribute), false).First() as ValueConversionAttribute).TargetType)
            throw new InvalidOperationException("Last target must be of type " + targetType.Name);
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion      
}
相关问题