比較事件驅動 UI 與資料繫結 UI
- 6 分鐘
事件驅動使用者介面 (UI) 是針對控制項所公開的事件所設計。 這些事件可以與觸發事件時叫用的事件處理程式程式代碼相關聯。 例如,假設您有一個按鈕,當按下時會執行耗時的操作。 指派給 Clicked 事件的事件處理常式可以啟動作業,然後將按鈕的 IsEnabled 屬性設定為 false,以防止在作業執行時再次按下按鈕。
資料繫結 UI 會使用資料繫結來呈現資料並與資料互動。 控制項的屬性會繫結至資料物件的屬性,且這些繫結可以偵測屬性中的變更。 使用上述範例,請考慮執行長時間執行作業的按鈕。 屬性不會停用程式碼後置中的按鈕,IsEnabled 屬性會繫結至資料物件的 IsBusy 屬性。 每當資料物件變成「忙碌」時,按鈕的啟用狀態會自動變更為相符。
使用事件和程式碼後置的優缺點
搭配程式碼後置使用控制項的事件處理常式,是設計 UI 應用程式邏輯時快速又便利的方式。 您可以使用程式碼呼叫服務來取得資料、在該資料上執行作業,以及與頁面上的控制項進行互動。 程式碼是用來保持 UI 和資料同步。
請考慮天氣服務應用程式的範例。 下列 XAML 片段包含使用者所選取以取得最新資料並以濕度更新 UI 的簡易 UI 按鈕。
<VerticalStackLayout Margin="10">
<HorizontalStackLayout Spacing="20">
<Label Text="Postal Code:" VerticalOptions="Center" />
<Entry x:Name="PostalCode" WidthRequest="100" />
<Button x:Name="RefreshWeatherButton" Text="Refresh" WidthRequest="200" Clicked="RefreshWeatherButton_Clicked" />
</HorizontalStackLayout>
<Label x:Name="Humidity" Text="Humidity: ?" />
</VerticalStackLayout>
此範例中有三個具名控制項:
- 名為 PostalCode 的
Entry控制項。 - 名為 RefreshWeatherButton 的
Button控制項。 - 名為 Humidity 的
Label控制項。
RefreshWeatherButton 具有針對 Clicked 事件宣告的事件處理常式。 按下按鈕時,事件處理程式會使用輸入控件中的 PostalCode 資料查詢氣象服務以獲取最新的氣象預報,並將 Humidity 標籤的文字設定為目前的濕度。
private void RefreshWeatherButton_Clicked(object sender, EventArgs e)
{
WeatherService.Location = PostalCode.Text;
WeatherService.Refresh();
Humidity.Text = $"Humidity: {WeatherService.Humidity}";
}
在此一個事件處理常式中,三個控制項會緊密結合在一起,以及透過程式碼後置的資料。
此設計非常適合小型 UI,但只要 UI 變得複雜,維護緊密結合的程式碼後置可能會變得麻煩。 如果您刪除或變更控制項,則必須使用這些 UI 控制項清除任何程式碼,其中包含事件處理常式。 如果您決定重新設計UI,您也會有許多程式代碼可重構。 當備份資料結構變更時,您必須深入探討每個 UI 的程式碼,才能保持同步。
資料繫結有助於
您可以在 XAML 或程式碼中實作數據系結,但它們在 XAML 中更為常見,這些系結有助於減少程式碼後置檔案大小。 當您將事件處理程式中的程式代碼取代為宣告式程式代碼或標記時,應用程式會簡化並釐清。 由於繫結不需要程式碼後置,因此您可以輕鬆地建立、改變或重新設計 UI,以符合您想要呈現資料的方式。
讓我們採用與上一節相同的範例,但更新它以使用資料繫結:
<VerticalStackLayout Margin="10">
<HorizontalStackLayout Spacing="20">
<Label Text="Postal Code:" VerticalOptions="Center" />
<Entry Text="{Binding Location, Mode=OneWayToSource}" WidthRequest="100" />
<Button Text="Refresh" Command="{Binding RefreshWeather}" WidthRequest="200" />
</HorizontalStackLayout>
<Label Text="{Binding Humidity}" />
</VerticalStackLayout>
您可以找出繫結資料的屬性,它們會針對屬性的值使用 XAML 擴充語法 {Binding ...}。 別擔心細節:我們稍後會在本課程模組中討論。
相同的三個控件會在 XAML 中宣告,但其中沒有任何名稱,因為不需要名稱:
Entry控件:此控件的Text屬性系結至名為Location的屬性。Button控件:按鈕的Command屬性會系結至名為RefreshWeather的屬性。Command是按鈕上的屬性,會在按下按鈕時叫用程式碼。 這是資料繫結中使用的Clicked事件替代方案。Label控件:此屬性Text系結至名為Humidity的屬性。
在這個簡單的 UI 中,會排除所有程式碼後置。 移除所有程式碼後置並不是資料繫結的重點,即使可行也一樣。 程式碼後置仍有其作用。 您實作的資料繫結量由您決定。
現在 UI 會鬆散地結合至資料物件。 為什麼鬆散結合,而不是緊密結合? 因為繫結的評估方式。 每個控制項都有 BindingContext 屬性。 如果未設定內容,則會使用父控制項的內容等等,直到評估 XAML 的根目錄為止。 評估繫結時,系統會檢查內容的物件執行個體是否有必要的屬性,例如繫結至內容 Humidity 屬性的標籤控制項 Text。 如果內容中不存在 Humidity,則不會發生任何動作。
因為UI是鬆散結合的,因此您可以重新設計UI,而不必擔心中斷程序代碼。 不過,您可以中斷功能。 例如,您可以刪除按鈕,而應用程式仍會編譯並執行,但您沒有重新整理天氣的方法。 另一方面,您可以將 Entry 和 Button 控制項取代為單一 SearchBar 控制項。 此控制項可讓您輸入文字並叫用命令。
<SearchBar Text="{Binding Location, Mode=OneWayToSource}" SearchCommand="{Binding RefreshWeather}" />
如您所見,在 UI 設計中使用資料繫結可協助您發展及變更 UI,而不需要太多工作。 它會自動讓UI與資料保持同步,而且應用程式邏輯會與UI分開。