NewYorker
NewYorker

Reputation: 73

Get Bound Selected Item from Combobox

My combo cbStudents is bound to StudentsList:

    <ComboBox Name="cbStudents"
        ItemsSource="{Binding Path=Students}"
        SelectedItem="{Binding Path=SelectedStudent, Mode=TwoWay}"
        DisplayMemberPath="Name"/>


    public class Student
    {
        private string _name;
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }

        private int _age;
        public int Age
        {
            get { return _age; }
            set { _age= value; }
        }
    }

I want to get the SelectedItem:

I tried-

    private ObservableCollection<Language> _students;

    public ObservableCollection<Language> Students
    {
        get { return _students; }
        set { _students= value; }
    }

    private string _selectedStudent;

    public string SelectedStudent
    {
        get { return _selectedStudent; }
        set { _selectedStudent= value; }
    }

    private void btnGetOutput(object sender, RoutedEventArgs e)
    {
        MessageBox.Show("Your selected item is: " + SelectedStudent);
    }

Result: I get Null output. No error code, nothing. Any help is appreciated.

Upvotes: 0

Views: 234

Answers (3)

Clemens
Clemens

Reputation: 128013

It seems you want to select a student by its name, i.e. a string.

Instead of SelectedItem, you should then use SelectedValue and SelectValuePath:

<ComboBox
    ItemsSource="{Binding Students}"
    DisplayMemberPath="Name"
    SelectedValuePath="Name"
    SelectedValue="{Binding SelectedStudent}" />

The view model would of course have to implement INotifyPropertyChanged and should declare the Students property as a readonly:

public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    public ObservableCollection<Student> Students { get; }
        = new ObservableCollection<Student>();

    private string selectedStudent;

    public string SelectedStudent
    {
        get { return selectedStudent; }
        set
        {
            selectedStudent = value;
            PropertyChanged?.Invoke(this,
                new PropertyChangedEventArgs(nameof(SelectedStudent)));
        }
    }
}

Upvotes: 2

Ali_Najaf
Ali_Najaf

Reputation: 11

You can implement INotifyPropertyChanged interface. As in the example below:

public class Data : INotifyPropertyChanged
{
    // boiler-plate
    public event PropertyChangedEventHandler PropertyChanged;
    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetValue<T>(ref T field, T value, string propertyName)
    {
        if (EqualityComparer<T>.Default.Equals(field, value)) return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
    
    private ObservableCollection<Language> _students;

    public ObservableCollection<Language> Students
    {
       get { return _students; }
       set { _students= value; }
    }

    private Language _selectedStudent;

    public Language SelectedStudent
    {
       get { return _selectedStudent; }
       set { SetValue(_selectedStudent, value, "SelectedStudent"); }
    }
}

Upvotes: 1

Michał Turczyn
Michał Turczyn

Reputation: 37337

First of all, you have defined ObservableCollection<Language> Students, I think it should be ObservableCollection<Student> Students instead.

Then, you have to bind to that collection, not to StudentList, which doesn't exist in your sample (maybe you didn't present full code?).

Then, you have to add items to that list somewhere, Students.Add(...).

Then, if items of your combo box are of type Student, then property bound to SelectedItem also must have type of Student, not string.

Last but not least: you have to bind class with all this fieelds defined to your view, so you must write: view.DataContext = objectWithData;, where view is your view and objectWithData is object with those fields defined.

Upvotes: 1

Related Questions