2016-03-29 2 views
0

У меня есть приложение wpf C#.Привязка комбинированного блока к наблюдаемому набору

Я использую поле со списком, и я установил свойство itemsource в наблюдаемую коллекцию.

Проблема заключается в том, что когда я изменяю эту коллекцию, изменения не отражаются в моем раскрывающемся списке.

, так что мне интересно, что я сделал не так?

Это мой класс объекта:

public class JobTicker 
{ 
    public string CustomerRef { get; set; } 
    public string JobRef { get; set; } 
    public int JobId { get; set; } 
    public string CustomerJobDetails { get; set; } 
    public string CustomerName { get; set; } 
} 

Я связываю к моей коллекции:

ActiveState.JobsActive = new ObservableCollection<JobTicker>('data from a list'); 

мое заявление переменной коллекции:

public static ObservableCollection<JobTicker> JobsActive = new ObservableCollection<JobTicker>(); 

My Combo Box (которая на userControl my, который загружается при запуске моего приложения)

<xctk:WatermarkComboBox x:Name="cboActiveJobs" Grid.Row="1" Grid.Column="2" 
    Width="250" Watermark="Select Customer"   
    DisplayMemberPath="CustomerJobDetails" 
    HorizontalContentAlignment="Center"      
    SelectionChanged="cbo_SelectionChanged" 
    DropDownOpened="cbo_DropDownOpened" 
    DropDownClosed="cbo_DropDownClosed" 
    Style="{StaticResource ComboBoxFlatStyle}" 
    /> 

и мой код позади:

cboActiveJobs.ItemsSource = ActiveState.JobsActive; 

Теперь, если я могу изменить «ActiveState.JobsActive» Я хотел бы ожидать изменения, которые будут отражены в моем раскрывающемся списке, но они не являются.

ответ

2

Код, который у вас на самом деле не является обязательным. Он просто присваивает коллекции свойство.

Свойство ItemsSource со списком не может получать уведомления от ObservableCollection. Вместо этого вам нужен экземпляр класса Binding, чтобы прослушать эти уведомления и сделать обновления пользовательского интерфейса. Binding - это где все волшебство. Вы можете создать программно в коде позади и прикрепить его (см ссылки ниже), но самый простой и далеко наиболее распространенным способом является связывание в XAML:

<xctk:WatermarkComboBox 

    ItemsSource="{Binding JobsActive}" 

    SelectedItem="{Binding SelectedCustomer}" 

    x:Name="cboActiveJobs" 
    Grid.Row="1" 
    Grid.Column="2" 
    Width="250" 
    Watermark="Select Customer"   
    DisplayMemberPath="CustomerJobDetails" 
    HorizontalContentAlignment="Center"      
    SelectionChanged="cbo_SelectionChanged" 
    DropDownOpened="cbo_DropDownOpened" 
    DropDownClosed="cbo_DropDownClosed" 
    Style="{StaticResource ComboBoxFlatStyle}" 
    /> 

Теперь, JobsActive должна быть публичной собственностью зрения модель, для которой DataContext. Если это не так, это не сработает.

Поскольку у вас есть событие SelectionChanged, я также добавил привязку SelectedCustomer, которая также будет принадлежать вашей модели. Binding обновит эти два способа: измените его в своей модели просмотра, и выбор combobox изменится. Когда пользователь выбирает элемент combobox, значение свойства viewmodel будет изменяться.

private JobTicker _selectedCustomer; 
public JobTicker SelectedCustomer { 
    get { return _selectedCustomer; } 
    set { 
     _selectedCustomer = value; 
     // If you're not in C#6, use this instead: 
     //OnPropertyChanged("SelectedCustomer"); 
     OnPropertyChanged(nameof(SelectedCustomer)); 
    } 
} 

// Implement INotifyPropertyChanged 
public event PropertyChangedEventHandler PropertyChanged; 
protected void OnPropertyChanged(string propName) 
{ 
    var handler = PropertyChanged; 
    if (handler != null) 
    { 
     handler(this, new PropertyChangedEventArgs(propName)); 
    } 
} 

Если вы хотите, чтобы получить это связывание работать сразу без написания ViewModel, я не рекомендую этот подход, но это абсолютно выполнимо. На StackOverflow есть несколько ответов, которые должны помочь в получении этой работы: WPF Binding Programatically, How to programmatically set data binding using C# xaml.

+0

это объяснит много. Спасибо :) –

+0

Мне нужно взглянуть на реализацию виртуальной машины. Это известно для меня в wpf, который вы видите. –

+0

@AndrewSimpson Ах, да. Большая часть WPF будет иметь больший смысл после того, как вы начнете связывать свойства с моделью представления. Не так много: либо выполнить [INotifyPropertyChanged] (https://msdn.microsoft.com/en-us/library/system.componentmodel.inotifypropertychanged (v = vs.110).aspx) и уведомления о пожаре. Для коллекций, которые будут использоваться пользовательским интерфейсом, используйте общий набор ObservableCollection, который вы уже используете. –

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