第二十四章:頁面導航(十三)

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類中的所有內容都可用。
讓我們看看它是如何工作的。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章