2015-04-23 11 views
7

Я пытаюсь использовать значение привязки в качестве параметра преобразователя, как показано на фрагменте кода ниже:Использование Binding, как ConverterParameter

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

Проблема в том, что метод EqualityConverter::Convert() вызывается с экземпляром Binding как (CompareTo), а не конкретное значение привязки.

Есть ли более разумный способ решить эту проблему? Я мог бы явно предоставить преобразованное свойство в моей модели представления, но я хотел бы знать, есть ли аналогичное рабочее решение для вышеупомянутого.

ответ

0

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) 
    { 

    } 
} 
+16

Я проигнорировал это, потому что речь идет о Xamarin Forms (см. Теги в OP). Код, который вы опубликовали, не работает с Xamarin, потому что 1) у Xamarin нет элемента управления TextBox, он называется Label и 2) Xamarin не поддерживает MultiBinding.Я не понимаю, почему этот ответ был принят, потому что он даже не отвечает на этот вопрос. –

+1

Что положить в 'ConvertBack'? Я не могу восстановить все свойства. – Ozkan

8

Другой, потенциально более простой способ сделать это, чтобы определить, связываемого свойство на самом преобразователе.

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}}"/> 

Это может занять немного тонкой настройки в результате должен быть чище, чем несколькими креплениями

+0

Это работало хорошо для меня. Я установил BindingContext моего конвертера в конструкторе представления в коде позади, как было предложено. Не забудьте установить x: Name на конвертере, чтобы на конвертор можно было ссылаться позади кода. – theguy

3

бился с такой же проблемой и не получить данных, которые я хотел. Вы не можете привязываться к «конвертерному параметру», то есть как это делается на текущей дате. Но я действительно хотел получить какие-то данные, отправленные в параметр. поэтому я нашел простое, но работающее решение, и я надеюсь, что он может работать и на вас. Начните с предоставления CompareTo x: Name = "CompareTo" или того, что вы хотите назвать.

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

Выполнение x: ссылку на фактическую отправку некоторых данных сейчас, вам просто нужно его захватить. Для меня значение, которое мне нужно, было значением «string», чтобы я мог выполнять определенные инструкции «If». Таким образом, вы могли бы сделать что-то похожее на:

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». Это должно работать и с другими объектами. Немного повезло, это приблизит вас к некоторому упрощенному «Multibinding» и ответу.

Надеюсь, это было полезно, поскольку это был мой первый пост в Stackoverflow!

Смежные вопросы