【问题标题】:Use Binding as ConverterParameter使用 Binding 作为 ConverterParameter
【发布时间】:2015-04-23 10:24:54
【问题描述】:

我正在尝试使用值绑定作为转换器参数,如下面的代码 sn-p 所示:

<Element
  Attribute="{Binding Value,
              Converter={StaticResource EqualityConverter},
              ConverterParameter={Binding CompareTo}}" />

问题是,EqualityConverter::Convert() 方法是使用 Binding 的实例作为转换器参数 (CompareTo) 调用的,而不是绑定的具体值。

有没有更聪明的方法来解决它?我显然可以在我的视图模型中提供转换后的属性,但我想知道是否有与上述类似的工作解决方案。

【问题讨论】:

    标签: c# xaml xamarin xamarin.forms


    【解决方案1】:

    另一种可能更简单的方法是在转换器本身上定义一个可绑定属性。

    public class CompareConverter: IValueConverter, INotifyPropertyChanged{
      private ComparisonType _comparison = ComparisonType.Equals;
      public ComparisonType Comparison {
        get {return _comparison; }
        set { _comparison = value; OnPropertyChanged(); }
      }
    
      private string _compareTo = null;
      public string CompareTo {
        get {return _compareTo; }
        set { _compareTo = value; OnPropertyChanged(); }
      }
    
      public event PropertyChangedEventHandler PropertyChanged;
    
      protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
      { 
        if (PropertyChanged != null) 
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
      } 
    
      public object Convert (object value, Type targetType, object parameter, 
         System.Globalization.CultureInfo culture)
      {
        bool result = false;
        switch (Comparison)...
        return result;
      } 
      ...
    }
    

    您也可以通过继承 BindableObject 并实现可绑定属性来做到这一点,如果绑定上下文未携带到资源中,您可能需要这样做。如果是这种情况,您可以在调用 Initialize 方法之后,在构造函数中从代码后面设置一次。

    您的 xaml 将如下所示:

    ..
    <ResourceDictionary>
      <myPrefix:CompareConverter x:Key="compareToY" Comparison="Equals" CompareTo="{Binding... }"/>
    </ResourceDictionary>
    ...
    <Control Value="{Binding X, Converter={StaticResource compareToY}}"/>
    

    可能需要稍微调整一下,结果应该比多重绑定更干净

    【讨论】:

    • 这对我来说效果很好。按照建议,我确实在代码后面的视图构造函数中设置了转换器的 BindingContext。请记住在转换器上设置 x:Name,以便可以在后面的代码中引用转换器。
    • 帮我解决了转换参数绑定的问题。尽管必须设置 x:Name 才能使其工作。否则我们会得到一个 nre
    【解决方案2】:

    我一直在努力解决同样的问题,但没有获得我想要的数据。您不能绑定到“converterParameter”,这就是它在当前日期的制作方式。但我真的很想将某种数据发送到参数。所以我找到了一个简单但有效的解决方案,我希望它也能对你有用。从给 CompareTo 一个 x:Name="CompareTo" 或任何你想称呼它的开始。

             <Element
              Attribute="{Binding Value,
              Converter={StaticResource EqualityConverter},
              ConverterParameter={x:reference CompareTo}}" />
    

    现在通过 x:reference 它实际上发送了一些数据,你只需要抓住它。对我来说,我需要的值是“字符串”值,这样我就可以执行某些“如果”语句。所以你可以做类似的事情:

        if(CompareTo == "myCoolString")
        {
          Value = "Well i guess i'm not so cool!"
        }
    

    这就是我从参数中获取数据的方式:

       public class MyConverter : IValueConverter
        {
    
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            if (parameter != null)
            {
                try
                {
                    var image = parameter as Image;
                    var src = image.Source as FileImageSource;
    
                    if (src.File.ToString() == "coolimage.png")
                    {
                        return "thumbsup.png";
                    }
                }
                catch
                {
                }
            } 
        }
    

    在我的情况下,我正在使用图像并且需要知道一个图像是否是“A”然后“B”需要更改为图像“C”。这也适用于其他对象。运气好的话,这将使您更接近一种简单的“多重绑定”和答案。

    希望这对我在 Stackoverflow 上的第一篇文章有​​所帮助!

    【讨论】:

      【解决方案3】:

      ConverterParameter 不是依赖属性,因此您将无法绑定任何属性。但是,您可以尝试将 MultiBinding 与 MultiValueConverter 一起使用。

      代码:

      <TextBox>
          <TextBox.Text>
              <MultiBinding Converter="{StaticResource MultiValueConverter}">
                  <Binding Path="property1"/>
                  <Binding Path="property2"/>
              </MultiBinding>
          </TextBox.Text>
      </TextBox>
      
      public class MultiValueConverter : IMultiValueConverter
      {
          public object Convert(object[] values, Type targetType, 
                 object parameter, System.Globalization.CultureInfo culture)
          {
               property1 = values[0];
               property2 = values[1];
               // Do your logic with the properties here.
          }
          public object[] ConvertBack(object value, Type[] targetTypes, 
                 object parameter, System.Globalization.CultureInfo culture)
          {
      
          }
      }
      

      【讨论】:

      • 我对此投了反对票,因为问题是关于 Xamarin Forms(请参阅 OP 中的标签)。您发布的代码不适用于 Xamarin,因为 1) Xamarin 没有 TextBox 控件,它称为 Label 和 2) Xamarin 不支持 MultiBinding。我不明白为什么这个答案被接受了,因为它甚至没有回答这个问题。
      • ConvertBack 中输入什么?我无法恢复所有属性。
      猜你喜欢
      • 2012-03-12
      • 2013-05-29
      • 2011-05-23
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 1970-01-01
      • 2011-04-28
      • 1970-01-01
      相关资源
      最近更新 更多