LUXS
LUXS

Reputation: 343

WPF ComboBox binding ItemsSource

I'm a beginner on WPF and trying to bind the Items of a ComboBox to an ObservableCollection

I used this code:

XAML

<Window x:Class="comboBinding2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        DataContext="{Binding RelativeSource={RelativeSource Self}}"
        Title="MainWindow" Height="350" Width="525">
    <Grid>
        <ComboBox x:Name="cmbTest" ItemsSource="{Binding Path=cmbContent}" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center" />
    </Grid>
</Window>

C#

public MainWindow()
{
    cmbTest.ItemsSource = cmbContent;
    cmbContent.Add("test 1");
    cmbContent.Add("test 2");

    InitializeComponent();
}

public ObservableCollection<string> cmbContent { get; set; }

I don't get any errors on this Code until I try to debug, it throws the error:

TargetInvocationError

An unhandled exception of type 'System.Reflection.TargetInvocationException' occurred in PresentationFramework.dll

Can anybody tell me what I'm doing wrong?

Upvotes: 11

Views: 72425

Answers (3)

SamTh3D3v
SamTh3D3v

Reputation: 9944

   public MainWindow()
    {

        InitializeComponent();
        cmbContent=new ObservableCollection<string>();
        cmbContent.Add("test 1");
        cmbContent.Add("test 2");
        cmbTest.ItemsSource = cmbContent;

    }
    public ObservableCollection<string> cmbContent { get; set; }

The code above don't use any binding, that's mean using it there no need to bind the Combobox's ItemSource, if you wan't to use binding you need to

First: Set the DataContext from the CodeBehind (ViewModel) using :

this.DataContext=this;

or from the Xaml:

DataContext="{Binding RelativeSource={RelativeSource Self}}">

Second : use the Binding in the ItemSource Just like you did ItemsSource="{Binding Path=cmbContent}" you may also considere using INotifyPropertyChanged Interface if you want to Notify the UI in case of any changes in a property

Upvotes: 3

d.moncada
d.moncada

Reputation: 17402

There are a few things wrong with your current implementation. As others have stated, your list is currently NULL, and the DataContext of the Window is not set.

Though, I would recommend (especially since you just started using WPF) is learning to do the binding the more 'correct' way, using MVVM.

See the simplified example below:

First, you want to set the DataContext of your Window. This will allow the XAML to 'see' the properties within your ViewModel.

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new ViewModel();
    }
}

Next, simply set up a ViewModel class that will contain all of the Window's binding elements, such as:

public class ViewModel
{
    public ObservableCollection<string> CmbContent { get; private set; }

    public ViewModel()
    {
        CmbContent = new ObservableCollection<string>
        {
            "test 1", 
            "test 2"
        };
    }
}

Lastly, update your XAML so that the binding path matches the collection:

<Grid>
    <ComboBox Width="200"
          VerticalAlignment="Center"
          HorizontalAlignment="Center"
          x:Name="cmbTest"
          ItemsSource="{Binding CmbContent}" />
</Grid>

Upvotes: 20

Tim
Tim

Reputation: 15247

cmbContent is null because you never set it to anything. I'm guessing the error is actually a NullReferenceException, but it is showing up as TargetInvocationException because it is in the constructor of a view.

Also, you're setting the ItemsSource of the ComboBox twice (once in the binding, once in the constructor). You don't need to do that. Pick one. Your binding won't work the way it is written (because the DataContext isn't set) so you should either go with doing it in code, or set up the DataContext (as suggested by Nadia).

Upvotes: 1

Related Questions