【发布时间】:2018-04-13 05:38:47
【问题描述】:
我的场景:有两个组合框绑定了SelectedItem 属性。
第一个组合框包含成本中心,第二个组合框包含所选成本中心的员工。
这意味着如果SelectedCostcentre 发生变化,INotifyPropertyChanged 会触发并搜索成本中心的所有员工。
视图模型:
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"/>
这很好用。
现在我为员工建立了一个搜索功能,可以在所有成本中心找到他们。如果我找到了,我需要以编程方式更改SelecedCostcentre 和SelectedEmployee。
这不会造成竞争条件吗?因为如果我设置SelectedCostcentre 属性PropertyChanged 会触发并设置Employees 属性。
private void SetEmployee(Employee employee)
{
SelectedCostcentre = Costcentres.Single(x => x.Id == employee.Costcentre.Id);
SelectedEmployee = Employees.Single(x => x.Id == employee.Id);
}
如何在没有竞争条件的情况下解决这个问题?
谢谢
【问题讨论】:
-
race-comndition 是错误的名称,这是单线程的。不过,您可能会触发级联事件,也可能触发循环事件。清楚你所观察到的。
标签: c# race-condition inotifypropertychanged