简体   繁体   English

您能否在 xaml 中的属性绑定上调用多个转换器,如果可以,如何调用

[英]Can you call more than one converter on a property binding in xaml, and if so how

I have a button defined in xaml whose visibility is bound to a dependency property using the standard BooleanToVisibility converter like so.我有一个在 xaml 中定义的按钮,它的可见性使用标准的 BooleanToVisibility 转换器绑定到依赖属性,就像这样。

 Visibility="{Binding Path=GoToButtonVisibility,Converter={StaticResource booltovis}, RelativeSource={RelativeSource TemplatedParent}}"

Now I also have a textbox whose read only property I would like to bind to the visibility of the button I mentioned above, except that it needs to be the opposite, so if the button isn't visible it's read only will be true, if not it will be false.现在我还有一个文本框,它的只读属性我想绑定到我上面提到的按钮的可见性,除了它需要相反,所以如果按钮不可见,它的只读属性将是真的,如果不会是假的。

That meant I needed some way of having Not x in my xaml.这意味着我需要某种方式在我的 xaml 中包含 Not x。 Stack overflow to the rescue with this answer.堆栈溢出来拯救这个答案。

So now I have a nice NotConverter, however I cant simply do something like this;所以现在我有一个不错的 NotConverter,但是我不能简单地做这样的事情;

 IsReadOnly="{Binding ElementName=PART_GoToButton, Path=Visibility, Converter={StaticResource NotConverter}}"

because the NotConverter will throw an invalid cast exception.因为 NotConverter 会抛出一个无效的强制转换异常。 I have no problem with that and I understand why.我对此没有任何问题,我明白为什么。 I do however like the principle of the not converter so my question(s) are as follows.然而,我确实喜欢非转换器的原理,所以我的问题如下。

1) in the xaml itself is it possible to invoke both converters on the same like such that they would produce the desired result. 1) 在 xaml 本身中,是否可以同时调用两个转换器,以便它们产生所需的结果。 2) assuming 1 isn't possible then it suggests the need for a visibility to Boolean convertor. 2) 假设 1 是不可能的,那么它表明需要对布尔转换器的可见性。 As the BooleanToVisibility converter is builtin I'm not sure how the convert and Convertback functions have been written and therefore how I would effectively reverse them.由于 BooleanToVisibility 转换器是内置的,我不确定 convert 和 Convertback 函数是如何编写的,因此我不确定如何有效地反转它们。 Any ideas?有任何想法吗?

Just bind to the same property, but through your not converter.只需绑定到相同的属性,但通过您的非转换器。 Your code for the text box would thus be:因此,您的文本框代码将是:

 IsReadOnly="{Binding Path=GoToButtonVisibility, Converter={StaticResource NotConverter}}"

Your NotConverter is this:你的 NotConverter 是这样的:

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value is bool)
            return !(bool)value;
        else
            return null;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value != null && value is bool)
        {
            return !(bool)value;
        }

        return null;
    }

There's no need to get the visibility of the button from the UI.无需从 UI 获取按钮的可见性。

you can create an aggregate converter like this:您可以像这样创建一个聚合转换器:

   public class ValueConverterGroup : List<IValueConverter>, IValueConverter
   {
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, string language)
    {
      return this.Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, language));
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
      throw new NotImplementedException();
    }

    #endregion

then combine converters in xaml:然后在 xaml 中组合转换器:

<conv:ValueConverterGroup x:Key="booleanToInvertedVisibilityConverter">
  <conv:BooleanNegationConverter />
  <conv:BooleanToVisibilityConverter />
</conv:ValueConverterGroup>

and then use that aggregate converter just as you would use any other:然后像使用任何其他转换器一样使用该聚合转换器:

             <Button Name="btnBuy" Content="Buy full version" Command="{Binding Path=CommandBuy}" HorizontalAlignment="Center" 
                Visibility="{Binding Path=IsPaidVersion, Converter={StaticResource booleanToInvertedVisibilityConverter}}"/>

Using the aggregate converter described in @Jogy's answer you can even use the following markup extension :使用@Jogy 的回答中描述的聚合转换器,您甚至可以使用以下标记扩展:

[MarkupExtensionReturnType(typeof(IValueConverter))]
public class ConverterChainExtension : MarkupExtension
{
    public ConverterChainExtension()
    {
    }

    public ConverterChainExtension(string converterNames)
    {
        this.ConverterNames = converterNames;
    }

    public string Separator { get; set; }

    [ConstructorArgument("converterNames")]
    public string ConverterNames { get; set; }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        List<IValueConverter> converters = new List<IValueConverter>();
        if (this.ConverterNames != null)
        {
            foreach (string converterName in this.ConverterNames.Split(new[] { this.Separator }, StringSplitOptions.RemoveEmptyEntries))
            {
                if (new StaticResourceExtension(converterName).ProvideValue(serviceProvider) is IValueConverter converter)
                {
                    converters.Add(converter);
                }
                else
                {
                    throw new InvalidOperationException($"Couldn't find the converter with name : '{converterName}'");
                }
            }
        }

        return new YourAggregateConverter(converters);
    }
}

After declaring the converters you want as resources ( BoolInverterConverter and BoolToVisibilityConverter ), you can use the markup extension like this :在将您想要的转换器声明为资源( BoolInverterConverterBoolToVisibilityConverter )后,您可以像这样使用标记扩展:

<Button Visibility="{Binding SomeProperty, Converter={ConverterChain Separator=/, ConverterNames=BoolInverterConverter/BoolToVisibilityConverter}}"/>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 使用转换器进行多个绑定? - Using a converter for more than one binding? 如何在 Silverlight XAML 中引用另一个名称空间中的绑定转换器? - How can I refer to a binding converter in another namespace in Silverlight XAML? XAML绑定到转换器 - XAML Binding to a converter 如何匹配多个字符的单词? - How can you match words with more than one character? 数据绑定+转换器不更新绑定属性-XAML-WPF - Data Binding + Converter doesn't update bound property - XAML - WPF 绑定Button.Enabled到多个属性 - Binding Button.Enabled to more than one property Windows中的项目中是否可以有多个App.xaml文件包含多个子项目(8) - Can more than one App.xaml file exist in the Project consist of more than one SubProjects in Windows(8) 如何将属性作为参数传递给 Converter 并且属性不在列表 itemsource 上下文 xaml - Xamarin - How can I pass a property as a param to Converter and property is outside of list itemsource context xaml - Xamarin 如何在解决方案资源管理器窗口中将多个文件附加到XAML - How to attach more than one file to a xaml in solution explorer window 如果可观察集合中对象的属性发生更改,则在XAML中调用转换器 - call converter in XAML if property of a object in the observable collection changes
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM