I have managed to bind ItemsSource and ComboBox lets me choose each option, but I cannot see which option has been chosen. ComboBox is just blank. XAML code:
<ComboBox
Name="Position"
Grid.Row="5"
SelectedValue="{Binding Position}"
ItemsSource="{Binding Positions}"
Style="{StaticResource MaterialDesignComboBox}"
Margin="15,10,15,10"
FontSize="12"/>
Tried basic ComboBox (non-material design) and results are identical.
I will provide more code if you need it, but so far it seems that this control is just broken, it doesn't work as it should. I'm probably missing some small detail how to properly set it up.
Edit
ViewModel:
public class WindowAddEmployeesViewModel : EmployeesViewModel, INotifyPropertyChanged
{
public ObservableCollection<PositionsViewModel> Positions { get; set; }
new public event PropertyChangedEventHandler PropertyChanged;
}
Base class contains things like FirstName, LastName, Position etc. INotifyPropertyChanged
not implemented because Fody.PropertyChanged does it for me.
PositionViewModel
:
public class PositionsViewModel : INotifyPropertyChanged
{
public string Position { get; set; }
public event PropertyChangedEventHandler PropertyChanged;
public override string ToString()
{
return $"{Position}";
}
}
Edit
Switching IsEditable
to True
makes it visible, but i don't want user to be able to edit it.
You misundestood the purpose of SelectedValue
. You can bind to the SelectedValue
instead of SelectedItem
. It has nothing to do with the value being displayed by the ComboBox
.
The displayed value can be defined by setting ItemsControl.DisplayMemberPath
to the desired property on the data model, but only when ItemTemplate
is not defined. DisplayMemberPath
is meant to replace the DataTemplate
in simple scenarios.
You obviously want to set the DisplayMemberPath
.
Also your current binding
<ComboBox SelectedValue="{Binding Position}" .../>
won't resolve (no matter the state of ComboBox.IsEditable
) as the DataContext
of the ComboBox
is obviously the WindowAddEmployeesViewModel
and not the PositionsViewModel
. This could've been a hint that you are using SelectedValue
wrong.
SelectedItem
: the currently selected data model.
SelectedValue
: returns the property's value on the SelectedItem
, defined by SelectedValuePath
.
SelectedValuePath
: sets the path to the property, which should be the SelectedValue
on the SelectedItem
. Argument is a string
.
DisplayMemberPath
: sets the path to a property on each data model which is used to display the item in the ComboBox
. Argument is a string
.
Data model
public class PositionsViewModel : INotifyPropertyChanged
{
public string Label { get; set; }
public string Position { get; set; }
public override string ToString() => Position;
}
The view
<!-- Since DisplayMemberPath="Position" the ComboBox will show the value of the Position property as its items -->
<ComboBox x:Name="PositionComboBox"
DisplayMemberPath="Position"
SelectedValuePath="Label"
ItemsSource="{Binding Positions}" />
<!--
Displays the PositionsViewModel. Implicitly invokes PositionsViewModel.ToString().
The TextBox will therefore display the property value of `PositionsViewModel.Position`.
-->
<TextBox Text="{Binding ElementName=PositionComboBox, Path=SelectedItem}" />
<!--
Displays the SelectedValue of the ComboBox. This value is defined by ComboBox.SelectedValuePath.
The TextBox will therefore display the property value of `PositionsViewModel.Label`
-->
<TextBox Text="{Binding ElementName=PositionComboBox, Path=SelectedValue}" />