Приложение со списком ничем не отличается от стандартного приложения Silverlight для Windows Phone 7, с той лишь разницей, что приложение со списком по умолчанию имеет список в виде меню и реализует шаблон проектирования MVVM с самого начала.
Начиная
Прежде всего, запустите Visual Studio 2010 и выберите « Новый проект» . В категории C # выберите Silverlight для Windows Phone, а там — Приложение Windows Phone List .
Как только вы нажмете OK , будет создан базовый шаблон, и вы увидите, что среда разработки настроена и готова.
Проект по умолчанию содержит много примеров данных, которые в этом случае не нужны. Я собираюсь удалить ненужные данные, чтобы иметь простой макет списка и ничего более.
Прежде всего, удалите папку SampleData из решения.
Теперь на главной странице ( MainPage.xaml ), а также на странице сведений ( DetailsPage.xaml ) удалите ссылку на DataContext, которая указывает на пример данных.
В том ViewModels папки, откройте MainViewModel.cs и удалить все элементы в Items ObservableCollection , но один из них (слева для экспериментальных целей).
Создайте и запустите приложение. Эмулятор Windows Phone 7 должен запуститься, и вот что вы должны увидеть (главное меню и открытый элемент):
Выглядит довольно просто и просто, но работает. Давайте посмотрим на детали этого приложения сейчас.
Копаем глубже — как это работает?
Если вы посмотрите на шаблон по умолчанию для главной страницы, вы увидите, что основная сетка состоит из трех отдельных частей.
А. Определения строк:
Эта часть в основном определяет, что сетка будет иметь две строки, одна из которых имеет высоту, которая будет автоматически рассчитываться на основе структуры содержимого, в то время как вторая строка будет занимать остальное пространство.
Б. Заявка и заголовок страницы:
Как видите, этот конкретный StackPanel занимает первую строку и содержит два несвязанных элемента TextBlock, которые описывают текущую страницу и приложение путем отображения их заголовков. Вы можете свободно изменять значения для свойств текста здесь.
C. Список:
Это основная часть главной страницы. Список привязан к коллекции объектов ObservableCollection, которую вы изменили в файле MainViewModel.cs . Каждый элемент, перечисленный там, также будет членом списка на главной странице.
Каждый элемент ListBox фактически представлен шаблоном данных, определенным экземпляром StackPanel , с изображением и двумя элементами TextBlock (используемыми для имени и описания), каждый из которых связан со свойством экземпляра ItemViewModel в коллекции ObservableCollection. ,
И это в значительной степени касается структуры главной страницы. Давайте посмотрим, что доступно на странице подробностей.
Его структура почти такая же, как и для главной страницы, единственное отличие заключается в привязке. DataContext для основной сетки устанавливаются в Items [0] , что , будучи выбранным элементом для страницы в ItemViewModel коллекции в MainViewModel экземпляре. Элемент TextBlock заголовка страницы привязан к LineOne , который является свойством внутри экземпляра ItemViewModel , который возвращается DataContext .
Последняя сетка используется для отображения описательной информации, а элемент TextBlock также связан со свойством внутри ItemViewModel.Экземпляр, возвращаемый элементом, связанным как DataContext для сетки.
Взгляд изнутри
Я упоминал связывание здесь несколько раз, поэтому давайте посмотрим, как выглядит экземпляр ItemViewModel . Для этого откройте файл ItemViewModel.cs внутри папки ViewModels . Вот структура класса:
public class ItemViewModel : INotifyPropertyChanged
{
private string lineOne;
public string LineOne
{
get
{
return lineOne;
}
set
{
if (value != lineOne)
{
lineOne = value;
NotifyPropertyChanged("LineOne");
}
}
}
private string lineTwo;
public string LineTwo
{
get
{
return lineTwo;
}
set
{
if (value != lineTwo)
{
lineTwo = value;
NotifyPropertyChanged("LineTwo");
}
}
}
private string lineThree;
public string LineThree
{
get
{
return lineThree;
}
set
{
if (value != lineThree)
{
lineThree = value;
NotifyPropertyChanged("LineThree");
}
}
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
По сути, есть три строковых свойства и событие, которое вызывается при изменении свойства. Каждый элемент, отображаемый на домашней странице, определяется экземпляром ItemViewModel .
Модель основного представления (может просматриваться в MainViewModel.cs ) использует преимущества существующего ItemViewModel для включения отдельных его экземпляров в ObservableCollection , но в то же время ее структура одинакова:
public class MainViewModel : INotifyPropertyChanged
{
public MainViewModel()
{
// Insert code required on object creation below this point
Items = new ObservableCollection<ItemViewModel>() {
new ItemViewModel() { LineOne = "runtime one", LineTwo = "Maecenas praesent accumsan bibendum", LineThree = "Facilisi faucibus habitant inceptos interdum lobortis nascetur pharetra placerat pulvinar sagittis senectus sociosqu"}
};
}
public ObservableCollection<ItemViewModel> Items { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (null != handler)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Когда приложение запускается, новый экземпляр MainViewModel инициализируется сразу после его вызова . После этого используется тот же экземпляр, если только вы не измените свойство.
// Static view model
private static MainViewModel viewModel = null;
public static MainViewModel ViewModel
{
get
{
// Delay creation of the view model until necessary
if (viewModel == null)
viewModel = new MainViewModel();
return viewModel;
}
}
Фактически, мы можем видеть, что он сначала вызывается внутри главной страницы, когда он загружается:
// When page is navigated to, set data context
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
// Set the data context of the listbox control to the sample data
if (DataContext == null)
DataContext = App.ViewModel;
}
Поэтому экземпляр MainViewModel автоматически создается при запуске приложения.
Итак, давайте посмотрим, как эти компоненты взаимодействуют.
В приложении есть статический экземпляр MainViewModel, который по умолчанию равен нулю. Когда основные загрузки страницы, он устанавливает его DataContext в App.ViewModel . То, как свойство структурировано, когда оно впервые запрашивается, оно автоматически создается. Следовательно, у нас есть статический экземпляр MainViewModel, который в то же время включает в себя коллекцию объектов ItemViewModel , которые определены внутри класса MainViewModel . Когда страница сведений загружается, она запрашивает необходимый экземпляр ItemViewModel и отображает назначенные ему свойства, которые привязаны к конкретным элементам управления.
Каждый раз, когда пользователь возвращается на главную страницу с помощью кнопки «Назад», используется новый экземпляр этой страницы. То же самое относится и к странице сведений.
Вещь, которую следует избегать
Одной из вещей, которых следует избегать при работе с приложением, структурированным как приложение списка, является непосредственная передача объектов пользовательского интерфейса в представление. Это не только нарушает правила разделения MVVM, но также может вызвать проблемы с привязкой. Как отметил Джеймс Эшли в этом потоке , было бы намного проще передать DataTemplate в существующее свойство, а не передать экземпляр UIElement.
Где я могу использовать приложение списка?
Везде, где вам нужно несколько вариантов и / или информацию, отображаемую различными способами. Сюда могут входить различные клиенты социальных сетей, приложения, которые хранят определенные данные, и в дальнейшем необходимо их отображать (конечно, с несколькими экземплярами различных данных), игры Silverlight и еще много чего.