Вы зашли как: Гость
Опрос
Верите ли вы в скорый выход Surface Andromeda?
14.07.2018 12:07 | dronov_va

Третья, заключительная, часть статьи, посвящённой использованию сложных списков в универсальных приложениях Windows 10.


1.4.2. Режим выбора щелчком

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

Чтобы включить у таблицы режим выбора щелчком, следует выполнить два действия:

  • обязательно задать для свойства SelectionMode таблицы значение None, чтобы отключить обычный выбор пунктов;
  • задать для свойства IsItemClickEnabled значение True, тем самым разрешив режим выбора щелчком.



Свойство IsItemClickEnabled мы можем задать в панели Свойства, где оно находится в ветви Разное.

При щелчке на пункте списка возникает событие ItemClick. Вторым параметром его обработчику передаётся объект класса ItemClickEventArgs, хранящий дополнительные сведения о событии. В числе этих сведений нас более всего интересует свойство ClickedItem, что возвращает объект, формирующий пункт таблицы, на котором был выполнен щелчок.

Давайте активизируем режим выбора щелчком для таблицы в нашем приложении ListView2 (как это сделать, мы уже знаем). После этого привяжем к событию ItemClick такой обработчик:

private void lsvLs_ItemClick(object sender, ItemClickEventArgs e)
{
this.lblLs.Text = (string)e.ClickedItem;
}


Запустим приложение и щёлкнем на каком-либо пункте таблицы. Мы увидим, что текст этого пункта появится в надписи внизу окна. Отметим также, что пункт, на котором мы щёлкнули, не выбирается (поскольку мы отключили в таблице возможность выбора пунктов).


1.4.3. Таблица с флажками

Если для свойства SelectionMode указать значение Multiple, левее каждого пункта таблицы появится флажок (рис. 8). Пользователь может выбирать пункты, просто устанавливая эти флажки.


Рис. 8. Таблица с флажками



Если в этом режиме выбора флажки нам не нужны, мы сможем убрать их, установив для свойства IsMultiSelectCheckBoxEnabled значение False. Задание значения True возвращает поведение таблицы по умолчанию, то есть вывод флажков.

Свойство IsMultiSelectCheckBoxEnabled доступно в ветви Разное панели Свойства.


1.4.4. Программный выбор пунктов

Если для таблицы задана возможность выбора всего одного пункта, мы можем выбирать пункты программо, присвоив:

  • индекс нужного пункта - свойству SelectedIndex;
  • объект, на основе которого был создан нужный пункт, - свойству SelectedItem.



Примеры:

// Выбираем первый пункт таблицы
this.lsvLs.SelectedIndex = 0;

// Выбираем пункт "PHP"
this.lsvLs.SelectedItem = "PHP";


Если же таблица позволяет выбирать несколько пунктов одновременно, для программного выбора пунктов можно использовать свойство SelectedItems. В хранящуюся в нём коллекцию нужно добавить объекты, на основе которых были созданы пункты, подлежащие выбору. Вот пример программного выбора пунктов "C#" и "C++":

this.lsvLs.SelectedItems.Add("C#");
this.lsvLs.SelectedItems.Add("C++");


Для выбора пунктов также можно использовать следующие методы класса ListView:



В обоих случаях <Диапазон> должен представляться объектом класса ItemIndexRange. Конструктор этого класса имеет формат вызова ItemIndexRange(<Индекс первого выбираемого пункта>, <Количество выбираемых пунктов>), где оба параметра задаются целыми числами.

Вот пример, в котором мы сначала выбираем первые 5 пунктов, а потом снимаем выбор с пунктов №№ 2 и 3:

this.lsvLs.SelectRange(new ItemIndexRange(0, 5));
this.lsvLs.DeselectRange(new ItemIndexRange(1, 2));


Метод SelectAll() делает выбранными все пункты таблицы.


1.5. Настройка параметров контейнера для пунктов таблицы

Для вывода набора пунктов таблица ListView использует объект класса ItemsStackPanel. Он выстраивает пункты в ряд, по вертикали или горизонтали, в зависимости от настроек. Также он поддерживает повторное использование объектов класса ListViewItem, представляющих пункты, с целью экономии системных ресурсов.

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

Контейнер, который будет выводить набор пунктов, задаётся посредством свойства ItemPanel таблицы. Значением этого свойства должен быть объект класса ItemPanelTemplate, в котором записывается XAML-код, формирующий задаваемый для таблицы контейнер с нужными параметрами.

Класс ItemStackPanel поддерживает следующие наиболее полезные для нас свойства:

  • Orientation - задаёт ориентацию, то есть направление, в котором выстраиваются пункты таблицы, в виде одного из элементов перечисления Orientation: Horizontal (горизонтальная) или Vertical (вертикальная; поведение по умолчанию);
  • GroupHeaderPlacement - задаёт местоположение шапки группы относительно самой группы пунктов. Значение указывается в виде элемента перечисления GroupHeaderPlacement: Top (над группой; поведение по умолчанию) или Left (левее группы, в результате чего сами пункты будут сдвинуты вправо);
  • GroupPadding - задаёт отступы между шапкой группы и остальным содержимым таблицы в виде значения типа структуры Thickness. По умолчанию отступы отсутствуют;
  • AreStickyGroupHeadersEnabled - если True, шапка группы при прокрутке содержимого таблицы временно остаётся наверху (поведение по умолчанию), если False - не остаётся, а прокручивается вместе с пунктами.



Мы можем поэкспериментировать с приложением ListView1, задавая для её таблицы различные параметры контейнера. Давайте, например, укажем местоположение шапки группы слева от пунктов и отступы в 5 пикселов со всех сторон. Для чего добавим в тег <ListView> такой XAML-код:

<ListView . . .>
. . .
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel GroupHeaderPlacement="Left" GroupPadding="5,5,5,5"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>


Если мы запустим приложение, то сразу увидим результат наших действий - рис. 9.


Рис. 9. Окно исправленного приложения ListView1. Шапки групп располагаются слева от самих групп



В случае, если мы решим указать у контейнера другую ориентацию, нам понадобится настроить встроенный в таблицу элемент управления ScrollViewer, который реализует прокрутку содержимого. Для этого мы используем следующие присоединённые свойства, которые указываются непосредственно у самой таблицы:

  • ScrollViewer.HorizontalScrollMode - управляет поддержкой горизонтальной прокрутки. Значением этого свойства должен быть один из элементов перечисления ScrollMode: Auto (горизонтальная прокрутка реализуется только при необходимости), Enabled (горизонтальная прокрутка реализуется в любом случае) или Disabled (горизонтальная прокрутка не реализуется; поведение по умолчанию);
  • ScrollViewer.VerticalScrollMode - управляет поддержкой вертикальной прокрутки. Значением этого свойства должен быть один из элементов перечисления ScrollMode: Auto (вертикальная прокрутка реализуется только при необходимости; поведение по умолчанию), Enabled (вертикальная прокрутка реализуется в любом случае) или Disabled (вертикальная прокрутка не реализуется);
  • ScrollViewer.HorizontalScrollBarVisibility - управляет наличием горизонтальной полосы прокрутки. Значением этого свойства должен быть один из элементов перечисления ScrollBarVisibility: Auto (горизонтальная полоса прокрутки появляется только при необходимости), Visible (горизонтальная полоса прокрутки всегда присутствует на экране), Hidden (горизонтальная полоса прокрутки скрыта, но сама прокрутка поддерживается) или Disabled (горизонтальная полоса прокрутки скрыта, и прокрутка не поддерживается; поведение по умолчанию);
  • ScrollViewer.VerticalScrollBarVisibility - управляет наличием вертикальной полосы прокрутки. Значением этого свойства должен быть один из элементов перечисления ScrollBarVisibility: Auto (вертикальная полоса прокрутки появляется только при необходимости; поведение по умолчанию), Visible (вертикальная полоса прокрутки всегда присутствует на экране), Hidden (вертикальная полоса прокрутки скрыта, но сама прокрутка поддерживается) или Disabled (вертикальная полоса прокрутки скрыта, и прокрутка не поддерживается).



Так, чтобы расположить пункты в таблице по горизонтали и разрешить горизонтальную прокрутку, нам следует вписать в тег <ListView> следующий код:

<ListView . . . ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollMode="Auto">
. . .
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsStackPanel . . . Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>



1.6. Программная прокрутка таблицы

Напоследок рассмотрим программные инструменты, которые поддерживаются классом ListView и реализуют прокрутку таблицы.

Метод ScrollIntoView() прокручивает таблицу таким образом, чтобы пункт, сформированный указанным в параметре объектом, появился в поле зрения. Это перегруженный метод, имеющий две разновидности:

  • ScrollIntoView(<Объект, формирующий пункт>) - если таблица прокручивается вверх, нужный пункт будет находиться у нижней границы элемента, если вниз - у верхней;
  • ScrollIntoView(<Объект, формирующий пункт>, <Выравнивание>) - дополнительно позволяет задать <Выравнивание>, указывающее, у какой границы таблицы будет находиться нужный пункт. <Выравнивание> задаётся в виде одного из элементов перечисления ScrollIntoViewAlignment: Default (то же самое поведение, что у первой разновидности этого метода) или Leading (нужный пункт всегда будет находиться у верхней границы таблицы).




2. GridView: перечень



Класс GridView представляет сложный список, названный автором статьи перечнем. Он выстраивает пункты по горизонтали, по строкам; строки же располагаются по вертикали, и по вертикали же выполняется прокрутка (если используются настройки по умолчанию). Можно сказать, что порядок расположения пунктов в таком списке схож с тем, согласно которому располагаются символы в тексте.


2.1. Базовые возможности перечня

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

Перечень имеет следующие отличия от таблицы:

  • для представления отдельного пункта используется класс GridViewItem, аналогичный знакомому нам классу ListViewItem;
  • для представления шапки группы используется класс GridViewHeaderItem, аналогичный классу ListViewHeaderItem;
  • в качестве контейнера для пунктов перечень использует класс ItemsWrapGrid, поддерживающий все возможности класса ItemsStackPanel плюс ещё несколько программных инструментов, о которых мы поговорим потом.



Пункты перечня нельзя растягивать на всю ширину или высоту элемента, иначе он не сможет их правильно выстроить.

Давайте сделаем новое приложение, выводящее, аналогично ListView1, список всех стандартных цветов, поддерживаемых платформой UWP, но теперь уже с применением перечня. Ради простоты не будем реализовывать в нём разное представление шапок для разных групп, а также создавать у перечня шапку и поддон.

Создадим проект GridView1. Добавим в него файл программного кода NC.cs с объявлением класса NamedColor; сам код объявления возьмём из приложения ListView1. Не забудем исправить имя пространства имён, в котором находится этот класс, на GridView1.

Переключимся на интерфейный код начальной страницы. Добавим в тег <Page>, создающий саму страницу, код, который сформирует представление для группировки цветов:

<Page . . .>
<Page.Resources>
<CollectionViewSource x:Name="cvsColors" IsSourceGrouped="True"/>
</Page.Resources>
. . .
</Page>


Поместим в тег <Grid>, который создаёт контейнер-сетку, такой довольно большой код:

<Grid . . .>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GridView x:Name="grvColors" Margin="10,10,10,10" ItemsSource="{Binding Source={StaticResource cvsColors}}">
<GridView.ItemTemplate>
<DataTemplate x:DataType="local:NamedColor">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="32"/>
<ColumnDefinition Width="32"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="96"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Rectangle Width="96" Height="96" Fill="{x:Bind Brush}" Grid.ColumnSpan="3"/>
<Border Background="#AAFFFFFF" Grid.ColumnSpan="3" Height="40" VerticalAlignment="Top">
<TextBlock Text="{x:Bind Name}" Margin="4,0,0,0" TextWrapping="Wrap"/>
</Border>
<Border Background="Gainsboro" Grid.Row="1" Grid.ColumnSpan="3"/>
<TextBlock Text="{x:Bind Color.R}" Foreground="Red" Grid.Row="1" HorizontalAlignment="Center"/>
<TextBlock Text="{x:Bind Color.G}" Foreground="Green" Grid.Column="1" Grid.Row="1" HorizontalAlignment="Center"/>
<TextBlock Text="{x:Bind Color.B}" Foreground="Blue" Grid.Column="2" Grid.Row="1" HorizontalAlignment="Center"/>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
<GridView.GroupStyle>
<GroupStyle HidesIfEmpty="True">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Text="{Binding Key}" FontSize="30" FontWeight="Bold" Margin="10,0,0,0"/>
</Grid>
</DataTemplate>
</GroupStyle.HeaderTemplate>
<GroupStyle.HeaderContainerStyle>
<Style TargetType="GridViewHeaderItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
<Setter Property="Background" Value="WhiteSmoke"/>
</Style>
</GroupStyle.HeaderContainerStyle>
</GroupStyle>
</GridView.GroupStyle>
</GridView>
</Grid>


Здесь нам, в принципе, всё знакомо и не требует пояснений.

Переключимся на функциональный код начальной страницы и добавим в код конструктора класса фрагмент, который создаст коллекцию цветов:

public sealed partial class MainPage : Page
{
public MainPage()
{
this.InitializeComponent();

IEnumerable<PropertyInfo> pis = typeof(Windows.UI.Colors).GetRuntimeProperties();
List<NamedColor> lncs = new List<NamedColor>();
PropertyInfo pi;
for (int i = 0; i < pis.Count(); i++)
{
pi = pis.ElementAt(i);
lncs.Add(new NamedColor(pi.Name, (Windows.UI.Color)pi.GetValue(null)));
}
var result = from lnc in lncs group lnc by lnc.Name.Substring(0, 1) into grp orderby grp.Key select grp;
this.cvsColors.Source = result;
}
}


Добавим в набор выражений импорта такое выражение, импортрующее пространство имён System.Reflection:

using System.Reflection;

Сохраним проект и запустим приложение на выполнение. Выглядит оно весьма стильно, не находите (рис. 10)?


Рис. 10. Окно приложения GridView1




2.2. Настройка параметров контейнера для пунктов перечня

Для вывода набора пунктов перечень GridView использует контейнер ItemsWrapGrid. Как и уже знакомый нам ItemsStackPanel, он реализует повторное использование объектов класса GridViewItem с целью экономии системных ресурсов.

Класс ItemsWrapGrid поддерживает свойства GroupHeaderPlacement, GroupPadding и AreStickyGroupHeadersEnabled, которые знакомы нам по классу ItemsStackPanel и ведут себя точно так же.

Свойство Orientation точно так же управляет ориентацией пунктов, а его значением должен быть элемент перечисления Orientation:

  • Horizontal - пункты перечня выстраиваются по горизонтали, по строкам, а строки располагаются по вертикали (поведение по умолчанию);
  • Vertical - пункты выстраиваются по вертикали, в столбцы, которые, в свою очередь, располагаются по горизонтали.



В качестве примера мы можем указать для перечня из приложения GridView1 вертикальную ориентацию, вставив в тег <GridView> следующий код:

<GridView . . . ScrollViewer.HorizontalScrollMode="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto"
ScrollViewer.VerticalScrollMode="Disabled" ScrollViewer.VerticalScrollBarVisibility="Disabled">
<GridView.ItemsPanel>
<ItemsPanelTemplate>
<ItemsWrapGrid Orientation="Vertical"/>
</ItemsPanelTemplate>
</GridView.ItemsPanel>
</GridView>


В результате мы получим перечень, показанный на рис. 11.


Рис. 11. Окно исправленного приложения GridView1. Для перечня указана вертикальная ориентация



Вот остальные полезные для нас свойства, поддерживаемые контейнером ItemsWrapGrid:

  • MaximumRowsOrColumns - указывает максимальное количество пунктов, которые будут присутствовать в одной строке (для горизонтальной ориентации) или одном столбце (для вертикальной ориентации). Значение по умолчанию - -1 (количество пунктов не ограничено);
  • ItemWidth - задаёт ширину пространства контейнера, выделяемого под размещение одного пункта, в виде вещественного числа в пикселах. Значение по умолчанию - Double.NaN или, если оно указывается в XAML-коде, Auto (ширина свободного пространства определяется шириной самого пункта);
  • ItemHeight - задаёт высоту пространства контейнера, выделяемого под размещение одного пункта, в виде вещественного числа в пикселах. Значение по умолчанию - Double.NaN или, если оно указывается в XAML-коде, Auto (высота свободного пространства определяется высотой самого пункта).



Их трудно отнести к числу часто применяемых, но в некоторых специфических случаях они могут пригодиться.

Дополнительные материалы



Владимир Дронов, MSInsider.ru Team
Июль 2018

Комментарии

Комментариев нет...
Для возможности комментировать войдите в 1 клик через

По теме

Акции MSFT
107.5 0.00
Акции торгуются с 17:30 до 00:00 по Москве
Мы на Facebook
Мы ВКонтакте
Все права принадлежат © MSInsider.ru (ex TheVista.ru), 2017
Сайт является источником уникальной информации о семействе операционных систем Windows и других продуктах Microsoft. Перепечатка материалов возможна только с разрешения редакции.
Работает на WMS 2.34 (Страница создана за 0.071 секунд (Общее время SQL: 0.031 секунд - SQL запросов: 31 - Среднее время SQL: 0.001 секунд))