Статьи

Отображение коллекций предметов на Windows Phone

Мобильные приложения часто должны отображать длинные списки элементов для пользователей. Они могут содержать изображения, текст или другие пользовательские компоненты. Каждая мобильная платформа имеет свой уникальный набор компонентов и концепций для отображения таких списков, и Windows Phone не является исключением. В этом уроке я покажу вам, как составить собственный список элементов, изменить их порядок, отобразить параметры и добавить элементы программным способом.

Вы можете скачать полный проект с GitHub .

Начиная

Создайте проект в Visual Studio и добавьте MainPage для переключения между нашими представлениями ListViewGridView.xaml, которые перенесут нас на соответствующие страницы.

 <Button x:Name="listViewButton" Content="List View" Grid.Row="0"/>

<Button x:Name="gridViewButton" Content="Grid View" Grid.Row="1"/>

Теперь создайте эти две страницы и назовите их GridViewPage и ListViewPage . Далее нам нужно создать связи между страницами и кнопками.

В режиме конструктора MainPage двойной щелчок по кнопке сгенерирует события onClick, и код xaml и C # будут добавлены автоматически.

Код для кнопок должен быть следующим.

 onClick

Если вы откроете MainPage.xaml.cs, вы увидите два метода, сгенерированные выше. Внутри них нам нужно вызвать Frame.Navigate для смены страниц.

 <Button x:Name="listViewButton" Content="List View" Grid.Row="0" Click="listViewButton_Click" />

<Button x:Name="gridViewButton" Content="Grid View" Grid.Row="1" Click="gridViewButton_Click" />

MainPage теперь завершена и должна выглядеть следующим образом, что позволяет переключаться между страницами.

Главная страница

Предметы

За каждым макетом списка находятся элементы, которые составляют запись в списке. Например, в списке контактов может быть имя контакта, номер телефона, изображение, электронная почта и т. Д.

Для нашего ListView я добавлю следующие элементы, чтобы создать контактную запись.

 private void listViewButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(ListViewPage));
}

private void gridViewButton_Click(object sender, RoutedEventArgs e)
{
    Frame.Navigate(typeof(GridViewPage));
}

Для GridView мы создадим клон магазина Windows. Это прекрасный пример отображения предметов внутри сетки.

 class ListViewItem
{
    public SolidColorBrush color { get; set; }
    public string firstName { get; set; }
    public string lastName { get; set; }
    public string mobileNumber { get; set; }
}

Я использовал цвета вместо картинок, и, надеюсь, это достаточно ясно. Убедитесь, что вы добавили, class GridViewItem
{
public SolidColorBrush color { get; set; }
public string name { get; set; }
public string price { get; set; }
public string rate { get; set; }
}
как зависимость для using Windows.UI.Xaml.Media; SolidColorBrushgetчтение / запись для каждого из параметров.

Переместите ListViewItem.cs и GridViewItem.cs в новую папку Items для более чистой структуры проекта.

модели

Для контроля нашего списка предметов мы будем использовать модели, которые являются мостом между кодом и дизайном. Если мы хотим внести изменения в отображаемые элементы, мы не должны изменять файл .xaml, а вместо этого изменить элемент в нашей модели, а остальное будет обработано во время выполнения.

Создайте ListViewModel.cs и GridViewModel.cs и переместите их в папку с именем Models .

Чтобы создать список элементов, нам нужен setObservableCollection Это так же, как простой список, но связывает элементы. Этот тип коллекции является ключом для динамического изменения элементов, поскольку он наследуется от System.Collections.ObjectModelINotifyCollectionChanged

В ListViewModel.cs добавить:

 INotifyPropertyChanged

Случайный — это тип данных для генерации случайных значений цвета, номера мобильного телефона и скорости. В конструкторе мы инициализируем как public static ObservableCollection<ListViewItem> ListViewItems { get; set; }
private static Random random;
ListViewItems

 random

Чтобы добавить элементы, нам нужен метод, который создаст элемент типа public ListViewModel()
{
ListViewItems = new ObservableCollection<ListViewItem>();
random = new Random();
}

 ListViewItem

Приведенные выше значения намеренно просты для демонстрации. Вы можете видеть, что все контакты имеют одинаковые имена, номера в качестве public static void AddItem()
{
ListViewItems.Add(new ListViewItem() {
firstName = "Contact",
lastName = (ListViewItems.Count + 1).ToString(),
mobileNumber = "+355-" + random.Next(10, 100) + "-" + random.Next(10,100) + "-" + random.Next(10,100) + "-" + +random.Next(100, 1000),
color = new SolidColorBrush(new Color() {
A = 255,
R = (byte)random.Next(255),
G = (byte)random.Next(255),
B = (byte)random.Next(255),
})
});
}
lastname

Примечание . Этот метод является статическим, поскольку при привязке элементов контейнера к mobileNumber

Таким же образом мы определяем модель для ListView

 GridView

Нам нужна последняя модель для этого проекта (я скоро объясню почему), которая включает обе модели, указанные выше. Я назвал его class GridViewModel
{
public static ObservableCollection<GridViewItem> GridViewItems { get; set; }
private static Random random;

public GridViewModel()
{
GridViewItems = new ObservableCollection<GridViewItem>();
random = new Random();
}

public static void AddItem()
{
GridViewItems.Add(new GridViewItem()
{
name = "APP NAME " + (GridViewItems.Count + 1),
price = "free",
rate = AddStars(random.Next(1,6)),
color = new SolidColorBrush(new Color()
{
A = 255,
R = (byte)random.Next(255),
G = (byte)random.Next(255),
B = (byte)random.Next(255),
})
});
}

private static string AddStars(int v)
{
string s = "";
for (int i = 0; i < v; i++)
s += "✰";

return s;
}
}
ViewModelListViewModel

 GridViewModel

Шаблоны данных

Мы хотим убедиться, что наши списки представлены привлекательным образом, и для этого нам нужно указать общий шаблон для наших данных в виде списка или сетки. Шаблоны характерны для представлений, содержащих элементы, такие как class ViewModel
{
public ListViewModel listViewModel { get; set; }
public GridViewModel gridViewModel { get; set; }

public ViewModel()
{
listViewModel = new ListViewModel();
gridViewModel = new GridViewModel();
}
}
ListView

Добавьте следующее в соответствующие файлы .xaml .

 GridView

и

 <ListView x:Name="listView" />

Простой способ добавить ItemTemplate в эти представления — из Представления проектирования . Щелкните правой кнопкой мыши на представлении и выберите « Редактировать дополнительные шаблоны» -> «Редактировать созданные шаблоны (шаблон элемента)» -> «Создать пустой…» .

DataTemplate

Назовите его ListViewItemTemplate или GridViewDataTemplate и убедитесь, что он определен внутри документа.

DataTemplate

Когда вы нажмете Ok , тег <GridView x:Name="gridView" />

 View

Вы увидите следующий код внутри тегов Page.

 ItemTemplate="{StaticResource ListViewDataTemplate}"

Замените </Page.Resources>
<DataTemplate x:Key="ListViewItemTemplate">
<Grid/>
</DataTemplate>
</Page.Resources>

 <Grid/>

И замените <Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>

<Rectangle Height="75" Width="75" Grid.RowSpan="2" Fill="{Binding color}" Margin="5"/>
<StackPanel Orientation="Horizontal" Grid.Column="1" VerticalAlignment="Bottom">
<TextBlock x:Name="firstNameTB" TextWrapping="Wrap" Margin="15,0" Style="{StaticResource ListViewItemTextBlockStyle}" Text="{Binding firstName}" FontSize="33.333"/>
<TextBlock x:Name="lastNameTB" TextWrapping="Wrap" Text="{Binding lastName}" Style="{StaticResource ListViewItemTextBlockStyle}" FontSize="33.333"/>
</StackPanel>
<TextBlock x:Name="numberTB" TextWrapping="Wrap" Text="{Binding mobileNumber}" Grid.Row="1" Grid.Column="1" Style="{StaticResource ListViewItemSubheaderTextBlockStyle}" VerticalAlignment="Top" Margin="15,0,0,0" FontSize="20"/>
</Grid>

 GridViewItemTemplate

Заметьте, что я использовал ‘binding’ в нескольких тегах, но как тег узнает, с каким свойством связываться? Чтобы сообщить компилятору, что <Grid Width="170">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Height="150" Width="150" Fill="{Binding color}" Margin="0,0,20,0" HorizontalAlignment="Left" VerticalAlignment="Top"/>
<TextBlock x:Name="nameTB" Style="{StaticResource ListViewItemTextBlockStyle}" FontSize="20" Text="{Binding name}" Grid.Row="1" HorizontalAlignment="Left" VerticalAlignment="Center" TextWrapping="WrapWholeWords"/>
<TextBlock x:Name="priceTB" TextWrapping="Wrap" Style="{StaticResource ListViewItemTextBlockStyle}" FontSize="20" Text="{Binding price}" Grid.Row="2" HorizontalAlignment="Left" Margin="0,0,0,5"/>
<TextBlock x:Name="ratingTB" TextWrapping="Wrap" Grid.Row="2" Style="{StaticResource ListViewItemContentTextBlockStyle}" FontSize="20" Text="{Binding rate}" HorizontalAlignment="Right" Margin="0,0,20,5"/>
</Grid>
{Binding name}

 DataContext

<Page.DataContext>
<local:ViewModel />
</Page.DataContext>
ViewModelGridViewListView

Добавление предметов

У нас есть код для добавления элементов списка, но мы еще не предоставили эту возможность пользователям. Для этого после тега DataContextPageResources

 AppBarButton

У нас есть событие click для кнопки, которая устанавливает обработчик в файле .xaml.cs .

 <Page.BottomAppBar>
    <CommandBar>
        <AppBarButton Icon="Add" Label="Add item" Click="AppBarButton_Click"/>
    </CommandBar>
</Page.BottomAppBar>

То же самое нужно добавить в private void AddAppBarButton_Click(object sender, RoutedEventArgs e)
{
ListViewModel.AddItem();
}
GridView

Последний шаг — указание представлению, откуда взять элементы, чтобы оно могло отображаться с указанным шаблоном. Внутри тега GridViewModel.AddItem();ListView

 GridView

и

 ItemsSource="{Binding listViewModel.ListViewItems}"

Запустите проект, чтобы увидеть результат до сих пор. Вы должны иметь возможность добавлять предметы.

Посмотреть список

Вид сетки

Изменение порядка предметов

Иногда вы можете захотеть изменить порядок элементов в списке. Это требует нескольких изменений в представлении.

Сначала добавьте следующие атрибуты в ItemsSource="{Binding gridViewModel.ListViewItems}"ListView

 GridView

Первый добавляет возможность изменить порядок элементов, но на устройстве вы должны перетащить элемент и поместить его в новую позицию, поэтому атрибуты должны быть установлены в CanReorderItems="True" CanDragItems="True" AllowDrop="True" Для устройств Windows этого достаточно, но на Windows Phone это не будет работать, поскольку режим переупорядочения по умолчанию отключен.

Я добавил два обработчика событий, trueHolding Первый используется для включения режима переупорядочения, когда пользователь удерживает один из элементов, а второй отключает его, фиксируя элементы на месте.

Код для просмотра Tapped

 listview

и для private void listView_Holding(object sender, HoldingRoutedEventArgs e)
{
listView.ReorderMode = ListViewReorderMode.Enabled;
}

private void listView_Tapped(object sender, TappedRoutedEventArgs e)
{
listView.ReorderMode = ListViewReorderMode.Disabled;
}

 gridview

Запустите и проверьте, удерживая предмет, пока он не начнет плавать. Затем снова удерживайте элемент, чтобы перетащить его куда угодно. После позиционирования нажмите любой элемент, чтобы закончить.

ListViewReordering

GridViewReordering

Вывод

Как видите, результаты выглядят хорошо. private void listView_Holding(object sender, HoldingRoutedEventArgs e)
{
gridView.ReorderMode = ListViewReorderMode.Enabled;
}

private void listView_Tapped(object sender, TappedRoutedEventArgs e)
{
gridView.ReorderMode = ListViewReorderMode.Disabled;
}
GridViewsListViews В этом руководстве потребовалось несколько шагов, чтобы начать, но создание списков в будущем будет быстрее и проще и станет неотъемлемой частью многих приложений.

Спасибо за уделенное время. Пусть код будет с вами! Пожалуйста, добавьте ваши комментарии или вопросы ниже.