2016-03-29 162 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泛型。 –