App類中介
在Xamarin.Forms應用程序中,在公共代碼項目中執行的第一個代碼是通常名爲App的類的構造函數,該類派生自Application。 在程序終止之前,此App對象保持不變,並且程序中的任何代碼都可以通過靜態Application.Current屬性使用它。 該屬性的返回值是Application類型,但將其強制轉換爲App很簡單。
這意味着App類是存儲必須在整個應用程序中訪問的數據的好地方,包括從一個頁面傳輸到另一個頁面的數據。
DataTransfer4版本程序中的Information類與您之前看到的版本略有不同:
public class Information
{
public Information()
{
Date = DateTime.Today;
}
public string Name { set; get; }
public string Email { set; get; }
public string Language { set; get; }
public DateTime Date { set; get; }
public override string ToString()
{
return String.Format("{0} / {1} / {2} / {3:d}",
String.IsNullOrWhiteSpace(Name) ? "???" : Name,
String.IsNullOrWhiteSpace(Email) ? "???" : Email,
String.IsNullOrWhiteSpace(Language) ? "???" : Language,
Date);
}
}
此版本的構造函數將Date屬性設置爲今天的日期。 在該程序的先前版本中,信息實例的屬性是從信息頁面上的各種元素設置的。 在這種情況下,Date屬性是從DatePicker設置的,默認情況下將其Date屬性設置爲當前日期。 在DataTransfer4中,如您所見,信息頁面上的元素是從Information對象中的屬性初始化的,因此在Information類中設置Date屬性只會使程序的功能保持一致。
這是DataTransfer4中的App類。 請注意名爲InfoCollection和CurrentInfoItem的公共屬性。 在創建DataTransfer4HomePage之前,構造函數將InfoCollection初始化爲ObservableCollection 對象:
public class App : Application
{
public App()
{
// Create the ObservableCollection for the Information items.
InfoCollection = new ObservableCollection<Information>();
MainPage = new NavigationPage(new DataTransfer4HomePage());
}
public IList<Information> InfoCollection { private set; get; }
public Information CurrentInfoItem { set; get; }
__
}
App中InfoCollection屬性的可用性允許DataTransfer4HomePage將其直接設置爲ListView的ItemsSource屬性:
public partial class DataTransfer4HomePage : ContentPage
{
App app = (App)Application.Current;
public DataTransfer4HomePage()
{
InitializeComponent();
// Set collection to ListView.
listView.ItemsSource = app.InfoCollection;
}
// Button Clicked handler.
async void OnGetInfoButtonClicked(object sender, EventArgs args)
{
// Create new Information item.
app.CurrentInfoItem = new Information();
// Navigate to info page.
await Navigation.PushAsync(new DataTransfer4InfoPage());
}
// ListView ItemSelected handler.
async void OnListViewItemSelected(object sender, SelectedItemChangedEventArgs args)
{
if (args.SelectedItem != null)
{
// Deselect the item.
listView.SelectedItem = null;
// Get existing Information item.
app.CurrentInfoItem = (Information)args.SelectedItem;
// Navigate to info page.
await Navigation.PushAsync(new DataTransfer4InfoPage());
}
}
}
請注意兩種不同但相似的方式,即實現Button的Clicked處理程序和ListView的ItemSelected處理程序。 在導航到DataTransfer4InfoPage之前,兩個處理程序都將App類的CurrentInfoItem屬性設置爲Information實例。 但Clicked處理程序將CurrentInfoItem屬性設置爲新實例,而ItemSelected處理程序將其設置爲ListView中的選定項。
其他所有內容都由DataTransfer4InfoPage處理。 info頁面可以從存儲在App類的CurrentInfoItem屬性中的Information對象初始化頁面上的元素:
public partial class DataTransfer4InfoPage : ContentPage
{
App app = (App)Application.Current;
public DataTransfer4InfoPage()
{
InitializeComponent();
// Initialize the views.
Information info = app.CurrentInfoItem;
nameEntry.Text = info.Name ?? "";
emailEntry.Text = info.Email ?? "";
if (!String.IsNullOrWhiteSpace(info.Language))
{
languagePicker.SelectedIndex = languagePicker.Items.IndexOf(info.Language);
}
datePicker.Date = info.Date;
}
protected override void OnDisappearing()
{
base.OnDisappearing();
// Set properties of Information object.
Information info = app.CurrentInfoItem;
info.Name = nameEntry.Text;
info.Email = emailEntry.Text;
int index = languagePicker.SelectedIndex;
info.Language = index == -1 ? null : languagePicker.Items[index];
info.Date = datePicker.Date;
// If the object has already been added to the collection, replace it.
IList<Information> list = app.InfoCollection;
index = list.IndexOf(info);
if (index != -1)
{
list[index] = info;
}
// Otherwise, add it.
else
{
list.Add(info);
}
}
}
信息頁面仍然需要覆蓋其OnDisappearing方法以設置Information對象的屬性,並可能將其添加到ListView集合或替換相同的對象以觸發重繪。 但是info頁面不需要直接訪問ListView,因爲它可以從App類的InfoCollection屬性獲取ObservableCollection。
此外,如果您需要保存和恢復頁面狀態,App類中的所有內容都可用。
讓我們看看它是如何工作的。