[英]MVVM and async properties
我有一個具有以下屬性的ViewModel
public Employee SelectedEmployee
{
get { return _selectedEmployee; }
set
{
if (value == _selectedEmployee) return;
_selectedEmployee = value;
if (_selectedEmployee != null)
{
StaffHolidaysViewModel.HolidayAllowance = _staffDataService.EmployeeHolidayAllowance(_selectedEmployee.Id);
FireEmployeeSelectedMessage(SelectedEmployee.Id);
}
RaisePropertyChanged();
RaisePropertyChanged(nameof(Allowance));
RaisePropertyChanged(nameof(Taken));
RaisePropertyChanged(nameof(Remaining));
RaisePropertyChanged(nameof(TotalAbsences));
RaisePropertyChanged(nameof(TotalSick));
RaisePropertyChanged(nameof(TotalNonSickAbsences));
RaisePropertyChanged(nameof(SelectedEmployeeLeavingDate));
UpdateCanExecuteChanged();
}
}
線
StaffHolidaysViewModel.HolidayAllowance = _staffDataService.EmployeeHolidayAllowance(_selectedEmployee.Id);
包含對我想進行異步處理的方法的調用。 我不知道該怎么做,因為SelectedEmployee是一個綁定屬性。
<ComboBox Name="StaffMembers" ItemsSource="{Binding FilteredEmployees}" SelectedItem="{Binding SelectedEmployee}" Width="200" BorderThickness="1" BorderBrush="DimGray">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
由於它是一個屬性,因此無法使其類型為Task<Employee>
異步綁定MVVM屬性的推薦方法是什么? 還是只是不可能?
從技術上講,讓屬性執行異步任務不是想法方法,因為它們需要返回值。
為什么? 讓我們從另一個角度來看它:
異步意味着UI線程將不會停止(UI在處理時不會掛起),而主處理線程將等待操作完成並獲得結果(考慮到您正在使用await
)。
當您定義綁定時,UI直接依賴於使用await的數據的屬性,這意味着UI必須等待( async
操作無法發生),因此無法使屬性async
,因此您不能使用await
。
我到目前為止一直使用的所有變通方法是:
.Result
的異步Task返回方法的屬性。 我已經嘗試過了,它實際上並沒有提供最好的輸出。 IAsyncOperation<>
而不是Task<>
。 這將為您提供調用.GetResults()
方法的優勢,該方法將為您提供結果,並且不會凍結UI線程。 有關更多信息,請參見此處 。 如果您沒有任何后處理結果提取操作要執行,請使用此選項。 Task<>
。 我在那里執行所有操作並驗證結果。 獲得所需結果后,只需更新屬性並調用RaisePropertyChanged
。 這樣,我也可以處理其他視圖處理或中間加載屏幕,而不必因無法停止處理線程而受到限制。 使用我在上面定義的三種方法之一。 他們都很好。 以下是一些用例的要點,以獲取游戲的得分表服務器為例:
IAsyncOperation<>
。 代碼處理不會停止,也不會等待過程獲取結果。 例如:您只是想獲取分數並顯示出來。 Task<>
返回方法。 例如:計算分數后,您要將整數值轉換為百分比。 .Result
但它對我從未奏效。 如果還有其他意見,請在評論中提及
包含對我想進行異步處理的方法的調用。
我有一篇關於異步MVVM數據綁定的文章。 從本質上講,我通常做的是建立一個數據綁定的Task
-我稱之為NotifyTaskCompletion
文章,縮短到NotifyTask
在我更新的庫 。
您可以通過將StaffHolidaysViewModel.HolidayAllowance
的類型從它的類型(我將其稱為THolidayAllowance
)更改為NotifyTask<T>
包裝器(例如, NotifyTask<THolidayAllowance>
)來使用它。
然后,您可以同步設置它:
StaffHolidaysViewModel.HolidayAllowance = NotifyTask.Create(
_staffDataService.EmployeeHolidayAllowanceAsync(_selectedEmployee.Id));
您在這里要做的是啟動 EmployeeHolidayAllowanceAsync
,然后用NotifyTask
包裝其Task
。 這是同步完成的,因此可以在屬性設置器中執行此操作。
然后,您的數據綁定也需要更新。 NotifyTask<T>
具有幾個可以使用的屬性 。 最明顯的是Result
,它將最終保存EmployeeHolidayAllowanceAsync
的結果(它返回默認值,直到EmployeeHolidayAllowanceAsync
完成)。 還有IsNotCompleted
和IsFaulted
,您將使用它們來向用戶指示數據尚未到達或存在一些錯誤。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.