WPF binding ComboBox to my ViewModel

I am trying to link my ViewModel with my ComboBox. I have a ViewModel class defined as follows:

class ViewModel { public ViewModel() { this.Car= "VW"; } public string Car{ get; set; } } 

I set this ViewModel as a DataContext in Window_Load as:

  private void Window_Loaded(object sender, RoutedEventArgs e) { this.DataContext = new CarModel(); } 

Then in my xaml I do this to bind my ComboBox to this ViewModel. I want to show "VW" by default in my ComboBox:

  <ComboBox Name="cbCar" SelectedItem="{Binding Car, UpdateSourceTrigger=PropertyChanged}"> <ComboBoxItem Tag="Mazda">Mazda</ComboBoxItem> <ComboBoxItem Tag="VW">VW</ComboBoxItem> <ComboBoxItem Tag="Audi">Audi</ComboBoxItem> </ComboBox> 

I have 2 questions:

  • How to set the default value selected in the Combo Box to "VW" (after loading the form, it should show "VW" in the combo box).
  • Instead of installing ComboBoxItems as stated in xaml above, how do I install it in my ViewModel and then load them into a ComboBox?

Thanks,

UPDATE: So far I have managed to implement this, but I get an error, as shown below in c-tor ViewModel:

 namespace MyData { class ViewModel { public ViewModel() { this.Make = ""; this.Year = 1; this.DefaultCar = "VW"; //this is where I get error 'No string allowed' } public IEnumerable<Car> Cars { get { var cars = new Car[] { new Car{Model="Mazda"}, new Car{Model="VW"}, new Car{Model="Audi"} }; DefaultCar = cars.FirstOrDefault(car => car.Model == "VW"); } } public string Make { get; set; } public int Year { get; set; } public Car DefaultCar { get; set; } } class Car { public string Model { get; set; } } } 
+5
source share
2 answers

Since you are going to use MVVM, it will be much better for you if you start thinking about objects for representing cars in your application:

  public class ViewModel { public Car SelectedCar{ get; set; } public IEnumerable<Car> Cars{ get { var cars = YOUR_DATA_STORE.Cars.ToList(); SelectedCar = cars.FirstOrDefault(car=>car.Model == "VW"); return cars; } } } public class Car { public string Model {get;set;} public string Make { get; set; } public int Year { get; set; } } 

Your xaml:

 <ComboBox SelectedItem="{Binding SelectedCar}", ItemsSource="{Binding Cars}" UpdateSourceTrigger=PropertyChanged}"/> 
+8
source
  • Default value: If you set viewModel.Car = "VW" , then it should automatically select this item in the combo box. To do this, you need to either implement INotifyPropertyChanged or install Car before setting the DataContext .

Running INotifyPropertyChanged might look like this:

 class ViewModel : INotifyPropertyChanged { private string car; public ViewModel() { this.Car = "VW"; this.Cars = new ObservableCollection<string>() { "Mazda", "VW", "Audi" }; } public string Car { get { return this.car; } set { if (this.car != value) { this.car = value; OnPropertyChanged(); } } } public ObservableCollection<string> Cars { get; } public event PropertyChangedEventHandler PropertyChanged; protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) { this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); } } 

2. Bind ItemsSource and SelectedItem .

 <ComboBox ItemsSource="{Binding Cars}" SelectedItem="{Binding Car, Mode=TwoWay}"> </ComboBox> 

You can also set ComboBox.ItemTemplate if your source or view is more complex than just displaying a string:

  <ComboBox.ItemTemplate> <DataTemplate> <TextBlock Text="{Binding}" /> </DataTemplate> </ComboBox.ItemTemplate> 

In the view model, just add a list property:

 public ObservableCollection<string> Cars { get; set; } 

It should not be an ObservableCollection , but this type will automatically update the user interface every time the collection changes.

+4
source

Source: https://habr.com/ru/post/1238421/


All Articles