I am new to WPF, C# and data binding. I am just trying to bind a simple combo box to an ObservedCollection. Here is the code:
public class Directory
{
private string _ikey;
public string IKey
{
get
{
return _ikey;
}
set
{
_ikey = value;
}
}
private string _ivalue;
public string IValue
{
get
{
return _ivalue;
}
set
{
_ivalue = value;
}
}
}
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public ObservableCollection<Directory> DirectoryList = new ObservableCollection<Directory>();
public MainWindow()
{
InitializeComponent();
DirectoryList = new ObservableCollection<Directory>();
Directory _dirtemp = new Directory();
_dirtemp.IKey = "1";
_dirtemp.IValue = "Steve";
DirectoryList.Add(_dirtemp);
_dirtemp = new Directory();
_dirtemp.IKey = "2";
_dirtemp.IValue = "John";
DirectoryList.Add(_dirtemp);
}
}
My xaml looks like this:
<Window x:Class="DataBindCombo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:DataBindCombo"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox Height="48" HorizontalAlignment="Left" Margin="70,104,0,0" Name="comboBox1" VerticalAlignment="Top" Width="310"
ItemsSource="{Binding Path=DirectoryList}"
DisplayMemberPath="IValue"
SelectedValuePath="IKey"
>
It seems like it should be simple. I was able to put the binding in the code behind and it worked fine, but I would like to have it bind through xaml.
Any ideas? TIA
Point the binding to your code behind:
What you need to do is set the ComboBox's DataContext equal to your ObservableCollection.
Code-behind:
Xaml:
Though, as others had noted, a better approach would be using the Model-View-ViewModel design pattern. This will keep the View (xaml part) separate from the "the business logic" . Here is a good example on how to bind a comboBox using MVVM.
http://mark-dot-net.blogspot.com/2009/03/binding-combo-boxes-in-wpf-with-mvvm.html
Paths in a binding are with respect to the local DataContext, not the containing Window. You have not set a DataContext for your Window, so WPF does not have an object on which to look up the DirectoryList property.
With your current object model, you need to set
this.DataContext = this;
in your MainWindow constructor. Now the MainWindow object will be the DataContext, and the DirectoryList binding will be resolved against the MainWindow object. (Longer term, a better practice is to move the data model out to a separate class, and set the DataContext to an instance of that class, but that's a separate issue.)Also, WPF can bind only to properties, not fields. Your DirectoryList attribute is currently a field; you will need to change it to a property.
You need to set the
DataContext
of the window. For example like this:There are a couple ways you can go about this. The basics are you need to make it so the XAML can see your collection. You can do this in an implicit manner by setting it to your DataContext. If this is the only thing you are binding then its a quick and dirty way of binding. It would look like this:
The other way is more sophisticated but probably what you will use more often. To do it You need to expose your collection in your MainWindow as a DependencyProperty and then bind to that value. It would look something like this:
This is also not the only way to accomplish it in this manner. In general rather than creating the list directly on the control you would create a view model. The MVVM pattern is the recommend way of creating your presentation, but my examples give you a way of getting functionality out there. You can play and experiment with different ways of doing this. I've discovered there are always multiple ways of doing things in WPF and its a matter of finding the one that fits the situation the best.