将组合框绑定到 ObservableCollection

Binding a combo box to an ObservableCollection

我有一个 wpf c# 应用程序。

我正在使用组合框,并且我已将其项目源 属性 设置为可观察的 collection。

我遇到的问题是,当我修改这个 collection 时,更改没有反映在我的下拉列表中。

所以我想知道我做错了什么?

这是我的 class object:

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; }
}

我绑定到我的 collection:

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

我对 collection 变量的声明:

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',我希望更改会反映在我的下拉列表中,但事实并非如此。

您拥有的代码实际上并未对其进行绑定。它只是将一个集合分配给 属性。

组合框的 ItemsSource 属性 无法侦听来自 ObservableCollection 的通知。相反,您需要 Binding class 的实例来侦听这些通知并进行 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 应该是视图模型的 public 属性,该控件的 DataContext。如果不是,那将行不通。

因为你有一个 SelectionChanged 事件,我还添加了一个 SelectedCustomer 绑定,它在你的视图模型上也是一个 属性。 Binding 将以两种方式更新:在您的视图模型中更改它,组合框选择将更改。当用户选择一个组合框项目时,视图模型的 属性 值将会改变。

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));
    }
}

如果您确实希望在不编写视图模型的情况下立即使此绑定工作,我不推荐这种方法,但它绝对可行。 Whosebug 上有几个答案应该有助于实现它:WPF Binding Programatically, How to programmatically set data binding using C# xaml