我有一个数据网格和两个组合框。数据网格包含文档,可以拥有文档的第一个组合框人员,第二个组合框具有在第一个组合框中选择的人员的电话号码。
第一个组合框始终包含所有可以拥有文档的人。
如果我未在数据网格中选择文档,但在第一个组合框中选择了一个人,则我想在第二个组合框中填充所选人的所有电话号码。 Bu我不想选择任何电话号码。
如果我在数据网格中选择一个文档,则要在第一个组合框中选择该文档的所有者,并在该文档中设置电话号码。
每次选择文档所有者时,我都会使用一种异步方法来获取数据(电话号码)。代码是这样的:
public Documents SelectedDocumentInDataGrid;
public Persons SelectedPersonInComboBox;
public PhoneNumbers SelectedPhoneNumberInComboBox;
这是我用于将视图绑定到视图模型的属性。我只是显示这个以简化代码。
现在,当我在数据网格中选择一个文档时的代码:
public ObservableCollection<Documents> Documents
{
get { return _documents; }
set
{
_documents = value;
base.RaisePropertyChangedEvent("Documents");
}
}
public Documents DocumentsSelectedItem
{
get { return _documentsSelectedItem; }
set
{
_documentsSelectedItem = value;
documentsSelectionChanged();
base.RaisePropertyChangedEvent("DocumentsSelectedItem");
}
}
public ObservableCollection<Persons> Owners;
{
get { return _owners; }
set
{
_owners = value;
base.RaisePropertyChangedEvent("Owners");
}
}
public Persons OwnersSelectedItem
{
get { return _ownersSelectedItem; }
set
{
_ownersSelectedItem = value;
ownersSelectionChanged();
base.RaisePropertyChangedEvent("OwnersSelectedItem");
}
}
public ObservableCollection<PhonesNumbers> PhoneNumbers
{
get { return _phoneNumbers; }
set
{
_phoneNumbers = value;
base.RaisePropertyChangedEvent("PhoneNumbers");
}
}
public PhonesNumbers PhoneNumbersSelectedItem
{
get { return _phoneNumbersSelectedItem; }
set
{
_phoneNumbersSelectedItem = value;
base.RaisePropertyChangedEvent("PhoneNumbersSelectedItem");
}
}
private void documentsSelectionChanged()
{
OwnersSelectedItem = Owners.FirstOrDefault(x => x.IDPerson == DocumentsSelectedItem?.IDOwner);
PhoneNumbersSelectedItem = PhoneNumbersSelectedItem.FirstOrDefault(x => x.IDPhoneNumber == DocumentsSelectedItem?.)IDPhoneNumber);
}
private async Task ownersSelectionChanged()
{
await myRepository.getPhonesNumbersAsync(OwnersSelectedItem?.IDPerson)
.ContinueWith((myTask) =>
{
PhonesNumbers = new ObservableCollection<PhonesNumbers>(await myTask);
},TaskScheduler.FromCurrentSynchronizationContext());
}
问题在于在OwnersSelectedItem的set属性中调用了异步方法。
原因是,每次选择所有者时,我都想填写电话号码的组合框。而且,如果我选择一个文档,则必须选择所有者和电话号码,这样我就可以重用所选所有者的代码集。
这样,在选择文档时所调用的方法中,我只需要选择所有者,然后选择电话号码即可。
问题在于,在所有者的集合中,我可以使用await,因为它是一个属性,所以当我选择一个文档并设置所有者时,它不必等待完成获取电话号码的过程,因此在下一行中,当我尝试选择电话号码时,我还没有电话号码,因此组合框为空。
我想知道在传递给线路选择电话号码之前,是否有其他方法可以等待完成所有者完成的设置。
谢谢。
答案 0 :(得分:2)
您不能在C#中拥有async
属性,因此不能在属性获取器或设置器中await
使用方法。
但是您可以从属性中删除设置器(不允许直接设置),而可以使用async
方法进行设置。
public Persons OwnersSelectedItem
{
get { return _ownersSelectedItem; }
}
public async Task SetOwnersSelectedItem(Person newPerson)
{
_ownersSelectedItem = newPerson;
await ownersSelectionChanged();
base.RaisePropertyChangedEvent("OwnersSelectedItem");
}
答案 1 :(得分:2)
关于代码的一件有趣的事情是,您混合使用了await
和ContinueWith
:
private async Task ownersSelectionChanged()
{
await myRepository.getPhonesNumbersAsync(OwnersSelectedItem?.IDPerson)
.ContinueWith((myTask) =>
{
PhonesNumbers = new ObservableCollection<PhonesNumbers>(await myTask);
},TaskScheduler.FromCurrentSynchronizationContext());
}
没有必要这样做-await
的目的是在任务完成后恢复您的代码。所以这样的事情应该没问题:
private async Task ownersSelectionChanged()
{
var phoneNumbers = await myRepository.getPhonesNumbersAsync(OwnersSelectedItem?.IDPerson);
PhonesNumbers = new ObservableCollection<PhonesNumbers>(phoneNumbers);
PhoneNumbersSelectedItem = PhonesNumbers.FirstOrDefault(x => x.IDPhoneNumber == DocumentsSelectedItem?.)IDPhoneNumber)
}
请注意,在此处获得列表后,您可以立即选择默认电话号码。这似乎是正确的选择。当用户选择其他所有者时,它将自动发生。
(注意。我已经在PhonesNumbers
而不是PhoneNumbersSelectedItem
中进行搜索,因为这样做更有意义?)