2015-11-01 1 views
0

У меня есть поле со списком, обозначенное следующим образом.Как связать поле со списком с другим значением, чем фактическое, смещая его?

<ComboBox SelectedIndex="{Binding Path=Bonkey}"> 
    <ComboBoxItem Content="Monkey" /> 
    <ComboBoxItem Content="Donkey" /> 
</ComboBox> 

Я привязка к объекту, который имеет Bonkey типов полей в виде целого числа, в соответствии с приведенной ниже декларацией.

class Thingy 
{ 
    public int Bonkey {get; set; } 
    ... 
} 

Несмотря на то, что он отлично работает и, как предполагается, существует программно-техническая проблема, которая меня поддерживает ночью. Индексы, сгенерированные в ручном знаке вверх, равны 0 и 1. Однако я знаю, что значения целых чисел будут равны 1 и 2. (Ie Monkey индексируется 0, когда относится к элементу со списком, но это фактическое значение в объект, используемый в качестве источника данных равен 1. Аналогично, обезьяны имеет индекс 1 в пункты выпадающего списка, но она соответствует 2 в объекте.)

Мой промежуточное решение было сбить 1 в конструктор непосредственно перед установление контекста данных, за которым следует удар по 1 при отображении представления. Он работает, но я не могу гордиться, так сказать.

public SomeDialog(Thingy thingy) 
{ 
    InitializeComponent(); 
    thingy.Bonkey--; 
    DataContext = thingy; 
} 
... 
private void Cancel_Click(object sender, RoutedEventArgs eventArgs) 
{ 
    DialogResult = false; 
    DataContext.Bonkey++; 
    Close(); 
} 
... 
private void Submit_Click(object sender, RoutedEventArgs eventArgs) 
{ 
    DataContext.Bonkey++; 
    ... 
} 

Как я могу это сделать больше, ну ... неудобно?

  1. Я не смог найти никаких атрибутов, чтобы явно устанавливать индексы элементов в поле со списком.
  2. Я пробовал использовать конвертеры, но каким-то образом я либо получил пустые вещи в поле со списком (без предварительного выбора), либо какое-то странное сообщение об ошибке, сообщающее мне, что я сделал boo-boo (и так как я даже не был уверен если это хороший подход, я отпустил его).
  3. Googling дал кучу результатов, ни одна из которых не дала мне ясности относительно того, как компенсировать ценность (хотя, честно говоря, я подозреваю, что я могу использовать слишком странные ключевые слова, потому что кажется, что такая проблема должна " ранее обсуждались).
+0

Создайте пользовательский 'IValueConverter', который бы смещал значение в обоих направлениях по статическому значению, например, передан в' КонвертерParameter' – dkozl

+0

@dkozl Итак, в принципе, опция №2? Наверное, я снова могу взломать его. Может быть, мои мозги устают, а мой дух уходит слишком рано. Возможно, вы захотите опубликовать это как ответ, чтобы я мог принять его в качестве ответа, если я получу его для работы. –

+0

Он должен отлично работать с преобразователем. Возможно, если вы разместите свой конвертер, мы сможем рассказать вам, что не так. – dkozl

ответ

1

Существует ряд вопросов, связанных с смещениями и реализациями IValueConverter. Но просматривая их, я не вижу того, что касается конкретного сценария привязки со смещением; многие из вопросов связаны с людьми, у которых уже есть работающий конвертер, но возникают другие проблемы, а другие связаны с сценариями, которые так или иначе более сложны, чем эта.

Итак, вот очень простая реализация смещения преобразователя:

class OffsetValueConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     int offset = int.Parse((string)parameter); 

     return (int)value - offset; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     int offset = int.Parse((string)parameter); 

     return (int)value + offset; 
    } 
} 

Используется так:

<ComboBox SelectedIndex="{Binding OffsetValue, 
          Converter={StaticResource offsetValueConverter1}, 
          ConverterParameter=1}"/> 

Где, конечно, у вас есть ресурс объявленного сделать экземпляр преобразователя доступен , например:

<Window.Resources> 
    <l:OffsetValueConverter x:Key="offsetValueConverter1"/> 
</Window.Resources> 

Существуют и другие варианты реализации, такие как предоставление сам экземпляр преобразователя является свойством устанавливать для управления смещением или указывать смещение как фактическое значение int, поэтому его не нужно анализировать, но эти подходы имеют свои собственные ограничения, такие как невозможность повторного использования одного и того же экземпляра для разных смещений или требует более подробного объявления в XAML, соответственно. Я думаю, что вышеизложенное обеспечивает хороший баланс между удобством и эффективностью.


Смотрите также похожие вопросы:
How can I bind one property to another property, offset by a specific amount?
Applying transforms from DataTemplates in WPF

There are others, но они, кажется, наиболее тесно связаны с вашим собственным сценарием.

+0

Это был потрясающий ответ. +1 для кода примера. Черт возьми, если я смогу придумать, почему я не работал, но мне все равно сейчас. Он работает, как предполагается, в соответствии с вашими спецификациями, поэтому я счастлив как огурец. –

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