4

Ok, I'm no newbie at programming or C# as such, I just can't seem to get WPF's databinding straight in my head. My colleagues are raving about it (and yes, I will ask them as well) but right now I'm stumped.

Here's what I'd like to do for starters:

As an example I've got a list of things like this:

List<Thing> thingList = Source.getList();

Now normally I'd go

foreach(Thing t in thingList)
{
    //add thing to combobox
}

But from what I can gather is that I can somehow not do this but use a databinding to populate the combobox for me.

What I can't seem to get is where do I put the 'thingList'? Do I make it a separate property somewhere? Where do I put that property?

I feel very stupid at the moment, as I've been struggling with this for a while now and I can't find any examples out there that make me understand this - probably very simple - concept.

Anyone out there willing to help me or point me at some step-by-step guide I might have missed?

Jeff LaFay
  • 12,882
  • 13
  • 71
  • 101
Alex Crouzen
  • 75
  • 1
  • 3
  • If it's anything like the Winforms Databinding, your combo box should have a `DataSource` property (or something similar), and you should be able to set `comboBox.DataSource = Source.getList();` As long as you've set the `DisplayMember` and `ValueMembers` the right thing will display, and SelectedValue will retrieve the object itself. – Chris Pfohl Mar 21 '11 at 19:52
  • Here are a couple of SO Questions that will get you started in the right direction: [Binding WPF ComboBox to a Custom List](http://stackoverflow.com/questions/561166/binding-wpf-combobox-to-a-custom-list) and [MVVM: Tutorial from start to finish](http://stackoverflow.com/questions/1405739/mvvm-tutorial-from-start-to-finish) – Metro Smurf Mar 21 '11 at 19:53
  • In WPF, things like ComboBoxes and ListViews are used as visual containers for the data. Build and edit your lists in code behind, or from a file, etc. and bind to the Control on the form. – coldandtired Mar 21 '11 at 20:38

3 Answers3

2

Use ObservableCollection<T> for databinding in WPF. Where T is your class. See example below

public class NameList : ObservableCollection<PersonName>
{
    public NameList() : base()
    {
        Add(new PersonName("A", "E"));
        Add(new PersonName("B", "F"));
        Add(new PersonName("C", "G"));
        Add(new PersonName("D", "H"));
    }
  }

  public class PersonName
  {
      private string firstName;
      private string lastName;

      public PersonName(string first, string last)
      {
          this.firstName = first;
          this.lastName = last;
      }

      public string FirstName
      {
          get { return firstName; }
          set { firstName = value; }
      }

      public string LastName
      {
          get { return lastName; }
          set { lastName = value; }
      }
  }

Now in XAML. Go to resource tag

<Window
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

  xmlns:c="clr-namespace:SDKSample"

  x:Class="Sample.Window1"
  Width="400"
  Height="280"
  Title="MultiBinding Sample">

  <Window.Resources>
    <c:NameList x:Key="NameListData"/>
  </Window.Resources>


<ListBox Width="200"
         ItemsSource="{Binding Source={StaticResource NameListData}}"  // Name list data is declared in resource
         ItemTemplate="{StaticResource NameItemTemplate}"
         IsSynchronizedWithCurrentItem="True"/>

xmnls:c will give you option to choose the class. Here you can choose c,d ,e x whatever but be sure it should be used earlier

H.B.
  • 166,899
  • 29
  • 327
  • 400
  • 1
    You only need to use an `ObservableCollection` when the collection is expected to change. If the collection is static, anything that implements `IEnumerable` will be fine. – Metro Smurf Mar 21 '11 at 19:57
  • Yes i know, it will be used when you need a two way binding otherwise simply datasource and datavalue member etc workss –  Mar 21 '11 at 19:59
  • This is mostly what I was looking for, yes. I know it's a very broad subject, but what you describe is mostly like the 'automatic' process I was thinking about. Thank you. – Alex Crouzen Mar 23 '11 at 11:56
1

When it comes to data-binding i've found that this page if read thoroughly answers most of the questions beginners have about it.

To answer the question: The alernative to adding all the items is to tell the ComboBox where to get its items from, this is done with the ItemsSource property.

You can either set this in XAML or in code, while you would need a binding expression in XAML a normal assignment should do in code:

comboBox.ItemsSource = thingList;

If you do not specify further how those objects in the list are to be displayed the ToString method will be called, unless overridden you will usually end up with the class-path of your object. There are two main ways of telling the application how to display the object:

The fist and more heavy option is Data Templates which is used for displaying complex data using controls (which in turn can have items and templates etc), the second way is using lightweight properties like DisplayMemberPath, which should be set to the name of the property which should be displayed (usually just a string).

If your list changes and the combo box should be updated on its own the source should implement INotifyCollectionChanged, in most cases you will use the standard implementation ObersableCollection<T>.

H.B.
  • 166,899
  • 29
  • 327
  • 400
0

Most people would use WPF Databinding to populate the combobox but you don't have to.

You can add the items via code if you want to.

It's easy to get trapped into doing everything as it "should" be done without have a good reason for doing it that way (BTW, I'm not recommending you manually add the items, I'm just saying you can).

List<Thing> thingList = Source.getList();

foreach(Thing t in thingList)
{
   combobox.Items.Add( t );
}
grantnz
  • 7,322
  • 1
  • 31
  • 38
  • This is probably the worst possible way to accomplish this and there are lots of good reasons not to do it this way. At the very least you should update your example to assign the collection to ItemsSource instead of adding each item individually. – John Bowen Mar 21 '11 at 23:26
  • I thought I made it clear that I wasn't recommending this way of populating the list. I was just responding to the statement "But from what I can gather is that I can somehow not do this". – grantnz Mar 22 '11 at 00:33