Reputation: 73
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
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
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
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