I am new to WPF, and I am interested can this be done or not. I hava a string datasource for my combobox controll defined in the MainWindow lie this:
public readonly ObservableCollection<string> _roles = new ObservableCollection<string>() { "User", "Admin", "Developer" };
I have a model defined:
public class LoginRequest : ValidationBase
{
private string _email;
private string _password;
private string _role;
[Required(ErrorMessage = "Email address is required")]
public string Email
{
get { return _email; }
set { SetValue(ref _email, value); }
}
[Required(ErrorMessage = "Password is required")]
[MinLength(8, ErrorMessage = "Password minimum length is 8 charachters.")]
public string Password
{
get { return _password; }
set { SetValue(ref _password, value); }
}
[Required(ErrorMessage = "Role is required")]
public string Role
{
get { return _role; }
set { SetValue(ref _role, value); }
}
}
This model is defines in xaml as my DataContext
<Window.DataContext> <model:LoginRequest /> </Window.DataContext>
In the form I have a ComboBox where I bind the Role property of my object. That works perfect if I set the combobox ItemSource property form the code like this:
cbRoles.ItemsSource = _roles;
But I am interested, can I do this i xaml? Here is my code snippet for my combobox.
<StackPanel Grid.Row="2"
Margin="5"
Orientation="Vertical">
<Label x:Name="lblRole"
Content="Role" />
<ComboBox ItemsSource="{Binding Path=Role,
UpdateSourceTrigger=PropertyChanged,
NotifyOnValidationError=True,
ValidatesOnDataErrors=True}"
DisplayMemberPath="{Binding SimpleStringProperty}"
SelectedValuePath="{Binding SimpleStringProperty}"
SelectedItem="{Binding SimpleStringProperty}"
IsSynchronizedWithCurrentItem="True"
Text="Select Option"
Margin="1"
Height="20"
x:Name="cbRoles"/>
</StackPanel>
In order to set the ComboBox.ItemsSource
from XAML you must use data binding. To use data binding, the source must be a public
property, which requires to convert the _roles
field to a public
property.
Since the items are plain string, it doesn't have any property and therefore no path. You can't select a property to provide the display value or selection value. ComboBox.DisplayMemberPath
and ComboBox.SelectedValuePath
must be removed.
Binding.UpdateSourceTrigger
is set to UpdateSourceTrigger.PropertyChanged
by default.
SimpleStringProperty
does not exist on LoginRequest
. SelectedItem
should bind to LoginRequest.Role
instead.
MainWindow.xaml.cs
partial class MainWindow : Window
{
public ObservableCollection<string> Roles { get; }
public MainWindow()
{
InitializeComponent();
this.Roles = new ObservableCollection<string>() { "User", "Admin", "Developer" };
}
}
MainWindow.xaml
<ComboBox ItemsSource="{Binding Path=Roles,
RelativeSource={RelativeSource AncestorType=Window}},
NotifyOnValidationError=True,
ValidatesOnDataErrors=True}"
SelectedItem="{Binding Role}"
IsSynchronizedWithCurrentItem="True" />