比較事件驅動 UI 與資料繫結 UI
事件驅動使用者介面 (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 分開。