Главная » Разработка для Windows Phone 7 » Совместное использование данных страницами Windows Phone 7

0

Не стоит забывать, что все страницы приложения имеют удобный доступ к классу App, производному от Application. Статическое свойство Application.Current возвращает объект Application, связанный с приложением, и его можно просто привести к App. Это означает, что

в классе App можно хранить данные для совместного использования несколькими страницами приложения.

В классе App проекта SilverlightShareData опишем простое открытое свойство:

Проект Silverlight: SilverlightShareData Файл: App.xaml.cs (фрагмент)

public partial class App : Application {

// открытое свойство для хранения данных, совместно используемых страницами public Color? SharedColor { set; get; }

}

В данном примере свойство Color описано не просто как Color, а как свойство, допускающее пустое значение. Это сделано для случаев, когда свойство Background панели содержимого (ContentPanel) не SolidColorBrush. Тогда свойство Background имеет значение null, и Color не должно в нем храниться. Если бы это свойство было типа Color, значение Color сохранялось бы в нем по умолчанию; значение null для Color соответствует прозрачному черному, что является неверным. Даже непрозрачный черный является неверным значением, если пользователь выбрал светлую цветовую схему.

Приложение практически ничем не отличается, только при касании TextBlock на MainPage обработчик сначала делает попытку сохранить цвет в новом свойстве класса App и уже после этого выполняет переход на SecondPage:

Проект Silverlight: SilverlightShareData Файл: MainPage.xaml.cs (фрагмент)

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs

args) {

if (ContentPanel.Background is SolidColorBrush) (Application.Current as App).SharedColor =

(ContentPanel.Background as SolidColorBrush).Color;

this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));

args.Complete(); args.Handled = true;

}

После этого перегруженный OnNavigatedTo в SecondPage выполняет доступ к этому свойству:

Проект Silverlight: SilverlightShareData Файл: SecondPage.xaml.cs (фрагмент)

protected override void OnNavigatedTo(NavigationEventArgs args) {

Color? sharedColor = (Application.Current as App).SharedColor;

if (sharedColor != null)

ContentPanel.Background =

new SolidColorBrush(sharedColor.Value);

base.OnNavigatedTo(args);

Аналогично при нажатии TextBlock на SecondPage обработчик сохраняет текущее значение цвета фона в класс App и только после этого вызывает GoBack:

Проект Silverlight: SilverlightShareData Файл: SecondPage.xaml.cs (фрагмент)

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs

args) {

if (ContentPanel.Background is SolidColorBrush) (Application.Current as App).SharedColor =

(ContentPanel.Background as SolidColorBrush).Color;

this.NavigationService.GoBack();

args.Complete(); args.Handled = true;

}

В классе MainPage также имеется перегруженный OnNavigatedTo, т.е. он тоже может извлекать сохраненный цвет и задавать его как фоновый цвет контейнера:

Проект Silverlight: SilverlightShareData Файл: MainPage.xaml.cs (фрагмент)

protected override void OnNavigatedTo(NavigationEventArgs args) {

Color? sharedColor = (Application.Current as App).SharedColor;

if (sharedColor != null)

ContentPanel.Background =

new SolidColorBrush(sharedColor.Value);

base.OnNavigatedTo(args);

}

Теперь при переходе со страницы на страницу передается и цвет страницы.

Использовать класс App как хранилище совместно используемых данных настолько удобно, что эта методика получила широкое распространение. Тем не менее, следует рассмотреть более структурированные решения, в которых задействованы только страницы, участвующие в переходах, без привлечения какого-либо стороннего класса, каким является App.

Кроме виртуального метода OnNavigatedTo, класс Page также определяет метод OnNavigatedFrom (При переходе от), который на первый взгляд кажется намного менее полезным, ведь в любом случае страница знает, что с нее выполняется переход, потому что только что был вызван метод Navigate или GoBack.

Но и OnNavigatedFrom, и OnNavigatedTo включают параметры события типа NavigationEventArgs, который описывает два свойства: Uri типа Uri и Content типа object. Эти свойства всегда определяют страницу, к которой выполняется переход.

Например, MainPage вызывает Navigate, передавая в него аргумент «/SecondPage.xaml». При вызове метода OnNavigatedFrom в него передаются аргументы события, где свойство Uri указывает на «/SecondPage.xaml» и свойство Content типа SecondPage. Это вновь созданный экземпляр SecondPage, который будет выведен на экран после перехода, и это наиболее удобный способ получить этот экземпляр. Далее вызывается метод OnNavigatedTo SecondPage с теми же параметрами события: Uri, указывающим на «/SecondPage.xaml», и объектом SecondPage.

Аналогично, когда SecondPage вызывает метод GoBack, вызывается метод OnNavigatedFrom, и в него передаются параметры, включающие свойство Uri, которое указывает на «/MainPage.xaml», и свойство Content с экземпляром MainPage. После этого вызывается метод OnNavigatedTo MainPage с теми же параметрами события.

Это означает, что во время выполнения метода OnNavigatedFrom класс имеет возможность задать свойство или вызвать метод класса страницы перехода.

Рассмотрим пример под названием SilverlightInsertData. Этот проект включает две страницы, MainPage и SecondPage, и XAML-файлы, аналогичные тем, которые были рассмотрены ранее. В классе MainPage нет какой-либо логики для реализации изменения цвета случайным образом, для получения цвета он использует SecondPage. SecondPage можно рассматривать как диалоговое окно, возвращающее случайное значение цвета в MainPage.

Привожу файл выделенного кода для MainPage почти полностью: Проект Silverlight: SilverlightInsertData Файл: MainPage.xaml.cs (фрагмент)

public partial class MainPage : PhoneApplicationPage {

public MainPage() {

InitializeComponent();

}

public Color? ReturnedColor { set; get; }

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs

args) {

this.NavigationService.Navigate(new Uri("/SecondPage.xaml", UriKind.Relative));

args.Complete(); args.Handled = true;

}

}

Обратите внимание на свойство ReturnedColor (Возвращенный цвет) типа Color необязательной определенности, точно так же как в классе App в предыдущем приложении.

Рассмотрим файл выделенного кода SecondPage:

Проект Silverlight: SilverlightInsertData Файл: SecondPage.xaml.cs (фрагмент)

public partial class SecondPage : PhoneApplicationPage {

Random rand = new Random();

public SecondPage() {

InitializeComponent();

}

void OnTextBlockManipulationStarted(object sender, ManipulationStartedEventArgs

args) {

this.NavigationService.GoBack(); args.Complete();

args.Handled = true;

protected override void OnManipulationStarted(ManipulationStartedEventArgs args) {

ContentPanel.Background = new SolidColorBrush( Color.FromArgb(255, (byte)rand.Next(255), (byte)rand.Next(255), (byte)rand.Next(255)));

base.OnManipulationStarted(args);

}

protected override void OnNavigatedFrom(NavigationEventArgs args) {

if (ContentPanel.Background is SolidColorBrush) {

Color clr = (ContentPanel.Background as SolidColorBrush).Color;

if (args.Content is MainPage)

(args.Content as MainPage).ReturnedColor = clr;

}

base.OnNavigatedFrom(e);

}

}

Как и в предыдущих приложениях, SecondPage при касании меняет цвет фона случайным образом и при касании TextBlock вызывает метод GoBack. Изменен перегруженный метод OnNavigatedFrom, который вызывается вскоре после вызова GoBack классом. Если доступно действительное значение SolidColorBrush, этот метод проверяет, выполняется ли переход к объекту типа MainPage. Если да, он сохраняет объект Color в свойстве ReturnedColor класса MainPage.

MainPage может извлечь значение этого свойства в своем перегруженном методе OnNavigatedTo:

Проект Silverlight: SilverlightInsertData Файл: MainPage.xaml.cs (фрагмент)

public partial class MainPage : PhoneApplicationPage {

protected override void OnNavigatedTo(NavigationEventArgs args) {

if (ReturnedColor != null)

ContentPanel.Background =

new SolidColorBrush(ReturnedColor.Value);

base.OnNavigatedTo(args);

}

}

По сути, MainPage вызывает SecondPage для получения значения Color, просто как обычное диалоговое окно. Но SecondPage всегда открывается с черным фоном (или белым, если выбрана светлая цветовая тема).

SecondPage не может инициализироваться из любого свойства MainPage, поскольку вызов OnNavigatedTo, получаемый SecondPage, не ссылается на исходную страницу. Для обеспечения симметричной функциональности в SecondPage необходимо было бы описать собственное открытое свойство Color, которое должно было бы быть инициализировано в перегруженном OnNavigatedFrom в MainPage.

Еще одним небольшим отличием в данном приложении является описание свойства ReturnedColor в SecondPage. При переходе MainPage к SecondPage в MainPage вызывается метод OnNavigatedFrom, сохраняющий экземпляр SecondPage, к которому выполняется переход, в одно из полей MainPage. По завершении выполнения SecondPage сохраняет значение Color в своем свойстве ReturnedColor и вызывает GoBack. После этого вызывается метод OnNavigatedTo в MainPage. MainPage может использовать сохраненный как поле экземпляр SecondPage для доступа к свойству ReturnedColor.

Такая схема кажется вполне жизнеспособной, но работает не всегда. Проблема в невозможности гарантировать, что переход с MainPage и возвращение к нему будет выполнен с одного и того же экземпляра SecondPage. Совсем скоро мы вернемся к этому вопросу и рассмотрим его более детально.

Источник: Чарльз Петзольд, Программируем Windows Phone 7, Microsoft Press, © 2011.

По теме:

  • Комментарии