my scenario: There are two comboboxes with a bound SelectedItem
property. The first combobox contains the costcentres and the second one the employees of the selected costcentre.
That means if SelectedCostcentre
changes, INotifyPropertyChanged
fires and searches for all employees in the costcentre.
ViewModel:
public abstract class SelectEmployeeViewModel : ViewModelBase
{
protected readonly Plant plant;
public ObservableCollection<Costcentre> Costcentres { get; protected set; }
public Costcentre SelectedCostcentre { get; set; }
public ObservableCollection<Employee> Employees { get; protected set; }
public Employee SelectedEmployee { get; set; }
public bool CostcentresEnabled
{
get { return Costcentres != null && Costcentres.Any(); }
}
public bool EmployeesEnabled
{
get { return Employees != null && Employees.Any(); }
}
protected SelectEmployeeViewModel(Window window, Page page, Plant plant) : base(window, page)
{
this.plant = plant;
PropertyChanged += SelectEmployeeViewModel_PropertyChanged;
Costcentres = mainController.CostcentreDao.GetByPlant(plant);
}
private void SelectEmployeeViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
switch (e.PropertyName)
{
case nameof(SelectedCostcentre):
SetEmployees();
break;
}
}
private void SetEmployees()
{
if (SelectedCostcentre != null)
Employees = mainController.EmployeeDao.GetByCostcentre(SelectedCostcentre);
else
Employees = new ObservableCollection<Employee>();
}
}
Xaml:
<ComboBox
ItemsSource="{Binding Costcentres}"
SelectedItem="{Binding SelectedCostcentre}"
DisplayMemberPath="DisplayName"
HorizontalAlignment="Left"
IsEnabled="{Binding CostcentresEnabled}"
Margin="81,61,0,0" VerticalAlignment="Top" Width="213"/>
<ComboBox
ItemsSource="{Binding Employees}"
SelectedItem="{Binding SelectedEmployee}"
DisplayMemberPath="DisplayName"
IsEnabled="{Binding EmployeesEnabled}"
HorizontalAlignment="Left" Margin="81,88,0,0" VerticalAlignment="Top" Width="213"/>
This works great. Now i build a search function for employees which can find them in all costcentres. If I found one, I need to change the SelecedCostcentre
and SelectedEmployee
programatically.
Doesn't this create a race condition? Because If I set the SelectedCostcentre
property PropertyChanged
fires and sets the Employees
property.
private void SetEmployee(Employee employee)
{
SelectedCostcentre = Costcentres.Single(x => x.Id == employee.Costcentre.Id);
SelectedEmployee = Employees.Single(x => x.Id == employee.Id);
}
How can I solve this without having a race condition?
Thanks
There is no race condition, because the whole thing happens on one thread.
SelectedCostcentre = Costcentres.Single(x => x.Id == employee.Costcentre.Id);
First setter of SelectedCostcentre
property is executed, which invokes PropertyChanged
(in your code I don't see it, but I assume that's just a typo). This in turn calls SelectEmployeeViewModel_PropertyChanged
handler and SetEmployees
. So after line above is executed - Employees
are populated for given selected Costcenter
, synchronously, without any race conditions.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.