2016-03-29 160 views
0

我有一個wpf c#應用程序。將組合框綁定到ObservableCollection

我正在使用組合框,並將其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>(); 

我的組合框(這是在我的應用程序啓動時加載的我的用戶控件)

<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類的實例來偵聽這些通知並使UI更新發生。 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將更新這兩種方式:在您的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)); 
    } 
} 

如果你想獲得這種結合就沒有寫一個視圖模型的工作,我不建議的做法,但它是絕對可行的。在StackOverflow上有幾個答案可以幫助你實現這個目標:WPF Binding ProgramaticallyHow 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)並適當地啓動通知。對於將要由UI使用的集合,請使用您已經使用的ObservableCollection泛型。 –