2014-09-24 5 views
0

Я создал пользовательский элемент управления, полученный из ListBox, и у меня возникают проблемы с получением «SelectedItemsList» для привязки к соответствующему свойству в модели представления.Multi-Select ListBox Binding Issue

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

MultiSelectListBox:

public class MultiSelectListBox : ListBox 
{ 
    public MultiSelectListBox() { } 

    public static readonly DependencyProperty SelectedItemsListProperty = 
     DependencyProperty.Register(
      "SelectedItemsList", 
      typeof(IList), 
      typeof(MultiSelectListBox), 
      new PropertyMetadata(default(IList))); 
    public IList SelectedItemsList 
    { 
     get { return (IList) GetValue(SelectedItemsListProperty); } 
     set { SetValue(SelectedItemsListProperty, value); } 
    } 
} 

декларация в MainWindow.xaml:

<local:MultiSelectListBox 
    DataContext="{StaticResource viewModel}" 
    DockPanel.Dock="Left" 
    Visibility="{Binding IsThailandFinal, Converter={StaticResource BoolToVisConverter}, FallbackValue=Visible}" 
    ItemsSource="{Binding SelectedOutputtapeList}" 
    SelectionMode="Multiple" 
    SelectedItemsList="{Binding SelectedOutputTapes, Mode=TwoWay}" 
    HorizontalAlignment="Right" 
    Background="DeepSkyBlue" 
    Foreground="MidnightBlue" 
    ScrollViewer.VerticalScrollBarVisibility="Visible" 
    Height="100" 
    Width="70" 
    Margin="5"/> 

View Model (упрощенно):

public class BTLogFrontEndViewModel : ViewModelBase 
{ 
    private List<string> selectedOutputTapes; 
    public BTLogFrontEndViewModel() 
    { 
     selectedOutputTapes = new List<string>(); 
    } 
    public List<string> SelectedOutputTapes 
    { 
     get 
     { 
      return selectedOutputTapes; 
     } 
     set 
     { 
      selectedOutputTapes = value; 
      OnPropertyChanged("SelectedOutputTapes"); 
     } 
    } 
} 
+0

Почтовый код для вашего ObservableCollection и вы видите какую-либо ошибку привязки в окне вывода Visual Studio? –

+0

ObservableCollection - это сборник .NET, не отображающий код. – kformeck

+0

Я имел в виду объявление 'SelectedOutputTapes', а не исходный код ObservableCollection. Кроме того, что вы подразумеваете под «Я имею проблемы»? Можете ли вы уточнить формулировку проблемы? –

ответ

0

Один из способов, чтобы не использовать пользовательские ListBox и использование объекты в вашем списке, которые расширяют INotifyPropertyChanged:

<ListBox 
    Width="70" 
    Height="100" 
    HorizontalAlignment="Right" 
    Margin="5" 
    Background="DeepSkyBlue" 
    DockPanel.Dock="Left" 
    Foreground="MidnightBlue" 
    ItemsSource="{Binding SelectedOutputtapeList}" 
    ScrollViewer.VerticalScrollBarVisibility="Visible" 
    SelectionMode="Multiple" 
    DisplayMemberPath="Description" 
    Visibility="{Binding IsThailandFinal, Converter={StaticResource BoolToVisConverter}, FallbackValue=Visible}"> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="{x:Type ListBoxItem}"> 
      <Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}"/> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 

Предполагая BTLogFrontEndViewModel ваш DataContext:

public class BTLogFrontEndViewModel : ViewModelBase 
{ 
    private ObservableCollection<OutputTapeViewModel> m_SelectedOutputtapeList; 

    public ObservableCollection<OutputTapeViewModel> SelectedOutputtapeList 
    { 
     get 
     { 
      return m_SelectedOutputtapeList; 
     } 
     set 
     { 
      m_SelectedOutputtapeList = value; 

      NotifyPropertyChanged("SelectedOutputtapeList"); 
     } 
    } 
} 

Где OutputTapeViewModel объявлен как:

public class OutputTapeViewModel : ViewModelBase 
{ 
    private string m_Description; 

    public string Description 
    { 
     get 
     { 
      return m_Description; 
     } 
     set 
     { 
      m_Description = value; 

      NotifyPropertyChanged("Description"); 
     } 
    } 

    private bool m_IsSelected; 

    public string IsSelected 
    { 
     get 
     { 
      return m_IsSelected; 
     } 
     set 
     { 
      m_IsSelected = value; 

      NotifyPropertyChanged("IsSelected"); 
     } 
    } 
} 

Важные вещи, чтобы отметить это на ListBox я добавил свойство DisplayMemberPath для использования из поле описания в классе OutputTapeViewModel для отображения в списке. Также он имеет стиль контейнера элементов, который привязывается к свойству OutputTapeViewModel.IsSelected при выборе в ListBox. Это OutputTapeViewModel.IsSelected позволяет использовать свойство BTLogFrontEndViewModel.SelectedOutputtapeList такими способами, как:

var selectedItems = SelectedOutputtapeList.Where(item => item.IsSelected); 

это работает только в вашем случае, если вы не заботитесь о накладных делает выражение LINQ.