将组合框绑定到 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。
我有一个 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。