Mike Malter
Mike Malter

Reputation: 1038

Databind Combobox in WPF

I'm trying to databind a combobox in WPF for the first time and I can't get it to happen.

The image below shows my code, can you please tell me what I am missing? I only want graphic stuff in the xaml.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Patient p = new Patient();
    this.cbPatient.DataContext = p.SelfListAll();
    this.cbPatient.DisplayMemberPath = "Name";
    this.cbPatient.SelectedValuePath = "PatientIDInternal";
}

...

enter image description here

Upvotes: 1

Views: 589

Answers (4)

Aphex
Aphex

Reputation: 7490

Short explanation: Just make the following change to your XAML:

<ComboBox ItemsSource="{Binding Path=patientList}" />

Then, in your Window_Loaded event handler, just add

this.DataContext = this

Then make a new member called patientList of type ObservableCollection<Patient>.


Long explanation:

You don't have a binding set up. You need to create one through XAML like this:

<ComboBox ItemsSource="{Binding Path=patientList}" />

Then, the combobox will look for a member or property called "patientList" on the object that is set as its DataContext. I'd recommend using an ObservableCollection for patientList.

Alternatively, to create one in code, you can follow the examples here:

http://msdn.microsoft.com/en-us/library/ms752347.aspx#specifying_the_binding_source

Binding myBinding = new Binding("patientList");
myBinding.DataContext = someObject; //whatever object has 'patientList' as a member
mycombobox.SetBinding(ComboBox.ItemsSourceProperty, myBinding);

This will set a binding on the mycombobox ComboBox with a path of patientList and a DataContext of someObject. In other words, mycombobox will show the contents of someObject.patientList (which would ideally be some ObservableCollection, so that updates to the collection notify the binding to update).

Upvotes: 2

Emond
Emond

Reputation: 50672

You need to set the ItemsSource property relative to the DataContext:

cbPatient.SetBinding(ItemsSourceProperty, new Binding());

EDIT

The ItemsSource property of the ComboBox is the property that should point to the collection of items to be shown.

The collection you are interested in, is in the DataContext.

The Binding is an object that keeps track of changes of the collection and reports them to the ComboBox and its Path is relative to the object in the DataContext.

Because the Binding also needs to know the ComboBox you use the static SetBinding method that ties the connection between ComboBox and the Binding.

As in your code the collection itself is in the DataContext, the Path is empty.

The ItemsSource property should point to the collection of Patients. Because the collection of Patients is already in the DataContext, the Binding's Path property is empty.

Suppose an class named Hospital has two properties: Patients and Docters (and perhaps more: Rooms, Appointments, ...) and you set the DataContext of the ComboBox to an instance of Hospital. Then you would have to set the Binding's Path Property to "Patients"

Now the ComboBox will display each item (Patient) in the collection. To specify how a single Patient should be displayed you need to set the ItemTemplate property of the ComboBox.

Upvotes: 0

Mike Malter
Mike Malter

Reputation: 1038

Ok, here is the answer to how to populate a combobox in WPF. First, thanks to everyone above who made suggestions. The part I was missing was that I was not populating the ItemsSource property but the DataContext property. Again, thanks to everyone for their help.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    Patient p = new Patient();
    this.cbPatient.ItemsSource = p.SelfListAll();
    this.cbPatient.DisplayMemberPath = "Name";
    this.cbPatient.SelectedValuePath = "PatientIDInternal";
    this.cbPatient.SelectedIndex = 0;
}

Upvotes: 0

Ed Bayiates
Ed Bayiates

Reputation: 11210

You need to actually add the binding, e.g.:

Binding binding = new Binding();
binding.Source = MySourceObject;
binding.Path = new PropertyPath("MyPropertyPath");
binding.Mode = BindingMode.OneWay;
BindingOperations.SetBinding(cbPatient, SomeDependencyProperty, binding);

Upvotes: 0

Related Questions