2012-02-15 3 views
0

Я хочу установить источник данных элементов управления в наблюдаемый набор пар значений ключа, но только для отображения ключевой части пары.Правильно установить привязку в WPF

У меня есть сторонний комбинированный сборник.

Я изменил класс datasource, который пришел с ним, так что он содержит пары пар ключей.

Вот класс:

public class DataSource : INotifyPropertyChanged 
    { 
     private ObservableCollection<KeyValuePair<string,string>> _items; 

     public DataSource(ObservableCollection<KeyValuePair<string, string>> items) 
     { 
      _items = items; 
     } 

     #region INotifyPropertyChanged Members 

     public event PropertyChangedEventHandler PropertyChanged; 
     private void OnPropertyChanged(string propertyName) 
     { 
      if (PropertyChanged != null) 
       PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
     } 

     #endregion 




     public ObservableCollection<KeyValuePair<string, string>> Items 
     { 
      get { return _items; } 
     } 

     private string _selectedItem = ""; 
     public string SelectedItem 
     { 
      get { return _selectedItem; } 
      set 
      { 
       _selectedItem = value; 
       OnPropertyChanged("SelectedItem"); 
      } 
     } 

     private ObservableCollection<KeyValuePair<string, string>> _selectedItems; 
     public ObservableCollection<KeyValuePair<string, string>> SelectedItems 
     { 
      get 
      { 
       if (_selectedItems == null) 
       { 
        _selectedItems = new ObservableCollection<KeyValuePair<string, string>> { new KeyValuePair<string,string>("ALL"," ") }; 
        SelectedItemsText = WriteSelectedItemsString(_selectedItems); 
        _selectedItems.CollectionChanged += 
         (s, e) => 
         { 
          SelectedItemsText = WriteSelectedItemsString(_selectedItems); 
          OnPropertyChanged("SelectedItems"); 
         }; 
       } 
       return _selectedItems; 
      } 
      set 
      { 
       _selectedItems = value; 
      } 
     } 

     public string SelectedItemsText 
     { 
      get { return _selectedItemsText; } 
      set 
      { 
       _selectedItemsText = value; 
       OnPropertyChanged("SelectedItemsText"); 
      } 
     } string _selectedItemsText; 


     private static string WriteSelectedItemsString(IList<KeyValuePair<string, string>> list) 
     { 
      if (list.Count == 0) 
       return String.Empty; 

      StringBuilder builder = new StringBuilder(list[0].Key); 

      for (int i = 1; i < list.Count; i++) 
      { 
       builder.Append(", "); 
       builder.Append(list[i]. 
); 
      } 

      return builder.ToString(); 
     } 
    } 

В коде позади меня:

DataSource ds = new DataSource(materialNames); 
      cmbLastEditors.DataContext = ds; 

И в моем XAML у меня есть:

<my1:MultiComboBox Name="cmbLastEditors" Grid.Row="8" Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" SelectionMode="Multiple" DisplaySeparator=", " ItemsSource="{Binding Items}" SelectedItems="{Binding SelectedItems}" /> 

Я хочу сделать что-то вроде

ItemsSource="{Binding Items.Key}" 

Может ли кто-нибудь мне помочь? Пожалуйста, дайте мне знать, если вам нужна дополнительная информация.

ответ

3

Для регулярных comboboxes у вас есть ValueMember и поле DisplayMember. Что работает аналогично DisplayMemberPath. См this ссылку для лучшего объяснения, но ваш ComboBox должен выглядеть следующим образом:

<my1:MultiComboBox Name="cmbLastEditors" 
        Grid.Row="8" Grid.Column="1" 
        VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
        SelectionMode="Multiple" DisplaySeparator=", " 
        ItemsSource="{Binding Items}" 
        SelectedItems="{Binding SelectedItems}" 
        DisplayMemberPath="Key" /> 

Конечно, я не уверен, если это работает с вашим списком третьей стороной.

Если это не сработает, вы можете использовать преобразователь значений в ItemTemplate Combobox. Например, добавьте конвертер в текстовый блок в ItemTemplate, где вы привязываете весь объект и используете конвертер, чтобы вернуть отображаемое значение ключа.

class MyKeyValueConverter : IValueConverter 
{ 
    public object Convert(object aValue) 
    { 
     var pair = aValue as KeyValuePair<string, string>; 
     return pair.Key; 
    } 
} 


<TextBlock Text="{Binding Path=., Converter={StaticResource myKeyValueConverter}}"/> 
+0

Блестящий. Большое спасибо: D Добавление DisplayMemberPath = «Ключ» обработал. – user589195

4

Вы можете сделать это, используя ItemTemplate для визуализации каждого элемента в списке. Что-то вроде этого:

<my1:MultiComboBox ...> 
    <my1:MultiComboBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding Key}"/> 
     </DataTemplate> 
    <my1:MultiComboBox.ItemTemplate> 
</my1:MultiComboBox> 

То есть, если предположить, что ваш пользовательский MultiComboBox поддерживает нормальную семантику WPF ItemTemplate.

+0

+1 Фактически лучше, чем моя идея, потому что я думал, что DataTemplate уже используется. Иногда я считаю более сложным, чем необходимо :) – dowhilefor

+0

Собственно, я забыл ValueMember/DisplayMember. Если пользовательский элемент управления поддерживает это, это проще. +1 вокруг :) –