Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 329
LUXS Avatar asked Feb 06 '15 19:02

LUXS


2 Answers

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>
like image 134
d.moncada Avatar answered Oct 14 '22 20:10

d.moncada


   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

like image 38
SamTh3D3v Avatar answered Oct 14 '22 21:10

SamTh3D3v