WPF How to Link ComboBox

I am trying to bind my ComboBox to a list of strings, and I would like it to display the default value after loading Window.

To do this, I created a ViewModel class, for example:

namespace MyData { class ViewModel { public ViewModel() { this.Name = ""; this.Age = 0; this.Address = ""; this.DateOfPurchase = DateTime.Now.AddDays(-30); this.CarModel = "VW"; //I want to set VW as default but options are Mazda, VW, Audi } public IEnumerable<String> CarModels { get { var carModels = new String[] {"Mazda", "VW", "Audi"}; //CarModel = cars.FirstOrDefault(car => CarModel == "VW"); //this is not needed return carModels; } } public string Name { get; set; } public int Age { get; set; } public string Address { get; set; } public DateTime DateOfPurchase { get; set; } public String CarModel { get; set; } } } 

Then I installed the DataSource Window in my ViewModel

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

Finally, I would like to bind my controls to this data. I did it for everyone else except my ComboBox. I would like for him to get an array of strings with models (Mazda, VW and Audi) as his ComboBoxItems, and by default be the second one, which is VW, once generates loads.

Then I bind it the same way in my XAML:

 <ComboBox Name="cbCarModels" SelectedItem="{Binding CarModel, UpdateSourceTrigger=PropertyChanged}" ItemsSource="{Binding CarModels}"> 

And it works!

+2
source share
3 answers

On top of my head

In xaml

 <Combobox ItemsSource="{Binding Path=CarModels}", SelectedItem="{Binding SelectedCar}/> 

You will need to create a ViewModel.SelectedCar model. Install it in vm.ctor

 this.SelectedCar = Cars[1] 

You may need to add Path=CarModels, Mode=TwoWay to the binding.

+2
source

If you intend to use MVVM using WPF (or any XAML-based language), then understand that the DataBinding Engine works with the INotifyPropertyChanged interface. The user interface subscribes to PropertyChanged events and updates the user interface elements based on the binding.

Here is an example, only with the relevant parts. Please note that I do not include the implementation of INPC, but there are many frameworks that provide an abstract base class, and if you do not want to go along this route, there are many resources that describe how to implement the INPC interface.

MyViewModel.cs:

 public class MyViewModel : INotifyPropertyChanged { public MyViewModel() { CarModels = new[] {"Mazda", "VW", "Audi"}; SelectedCarModel = "VW"; } public IEnumerable<string> CarModels { get; private set; } private string _selectedCarModel; public string SelectCarModel { get { return _selectedCarModel; } set { if (_selectedCarModel == value) return; _selectedCarModel = value; OnPropertyChanged("SelectedCarModel"); } } } 

XAML:

 <ComboBox ItemsSource="{Binding Path=CarModels, Mode=OneTime}" SelectedItem="{Binding Path=SelectedCarModel}" /> 

Simply put, if you implement INPC and you receive a notification about a property change, the DataBinding mechanism will call the get methods of the property based on the property name. Then it will update the necessary user interface control. In addition, the user interface will also update the viewmodel.

+1
source

In addition, it is sometimes more convenient to communicate with complex objects (for example, when editing the properties of existing objects). To do this, you, as you suggested, can overwrite the ToString() method of this object, but you can also bind the display value in the combobox element to the secondary member of this object in XAML using the DisplayMemberPath property:

 <ComboBox ItemsSource="{Binding CarModel}" DisplayMemberPath="Name" SelectedItem="{Binding CarModels}" /> 

The advantage is that you save this extra ToString() code from your POCOs.

+1
source

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


All Articles