Поделиться через


Добавьте представление и модель для всех заметок

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

Несколько заметок и навигации

В настоящее время в представлении заметки отображается одна заметка. Чтобы отобразить все сохраненные заметки, создайте новое представление и модель : AllNotes.

  1. В области Обозреватель решений щелкните правой кнопкой мыши папку Views /> и выберите Add>New Item...
  2. В диалоговом окне "Добавление нового элемента" выберите WinUI в списке шаблонов в левой части окна. Затем выберите шаблон пустой страницы (WinUI). Назовите файл AllNotesPage.xaml и нажмите клавишу Add.
  3. В области Обозреватель решений щелкните правой кнопкой мыши папку Models /> и выберите Add>Class...
  4. Назовите класс AllNotes.cs и нажмите клавишу Add.

Подсказка

Вы можете скачать или просмотреть код для этого руководства из репозитория GitHub. Чтобы просмотреть код как на этом шаге, см. этот коммит: все представления заметок и модели.

Кодирование модели AllNotes

Новая модель данных представляет данные, необходимые для отображения нескольких заметок. Здесь вы получите все заметки из локального хранилища приложения и создадите коллекцию объектов Note, которые будут отображены в AllNotesPage.

  1. В области Обозреватель решений откройте файл Models\AllNotes.cs.

  2. Замените код в AllNotes.cs файле следующим кодом:

    using System;
    using System.Collections.Generic;
    using System.Collections.ObjectModel;
    using System.Threading.Tasks;
    using Windows.Storage;
    
    namespace WinUINotes.Models
    {
        public class AllNotes
        {
            public ObservableCollection<Note> Notes { get; set; } = 
                                        new ObservableCollection<Note>();
    
            public AllNotes()
            {
                LoadNotes();
            }
    
            public async void LoadNotes()
            {
                Notes.Clear();
                // Get the folder where the notes are stored.
                StorageFolder storageFolder = 
                              ApplicationData.Current.LocalFolder;
                await GetFilesInFolderAsync(storageFolder);
            }
    
            private async Task GetFilesInFolderAsync(StorageFolder folder)
            {
                // Each StorageItem can be either a folder or a file.
                IReadOnlyList<IStorageItem> storageItems = 
                                            await folder.GetItemsAsync();
                foreach (IStorageItem item in storageItems)
                {
                    if (item.IsOfType(StorageItemTypes.Folder))
                    {
                        // Recursively get items from subfolders.
                        await GetFilesInFolderAsync((StorageFolder)item);
                    }
                    else if (item.IsOfType(StorageItemTypes.File))
                    {
                        StorageFile file = (StorageFile)item ;
                        Note note = new Note()
                        {
                            Filename = file.Name,
                            Text = await FileIO.ReadTextAsync(file),
                            Date = file.DateCreated.DateTime
                        };
                        Notes.Add(note);
                    }
                }
            }
        }
    }
    

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

Замечание

Метод LoadNotes использует async void вместо async Task, поскольку вызывается из конструктора, который не может быть async. Этот шаблон "fire-and-forget" является допустимым здесь, так как метод представляет собой процедуру инициализации, подобную событию.

В Notes коллекции используется ObservableCollection, которая является специализированной коллекцией, которая хорошо работает с привязкой данных. Если элемент управления, который перечисляет несколько элементов, например ItemsView, привязан к ObservableCollection, они работают вместе, чтобы автоматически поддерживать список элементов в синхронизации с коллекцией. Если элемент добавляется в коллекцию, элемент управления автоматически обновляется с помощью нового элемента. Если элемент добавляется в список, коллекция обновляется.

Дополнительные сведения см. в документации:

Теперь, когда модель AllNotes готова предоставить данные для представления, необходимо создать экземпляр модели в AllNotesPage, чтобы представление могло получить доступ к модели.

  1. В области Обозреватель решений откройте файл Views\AllNotesPage.xaml.cs.

  2. В этом классе добавьте следующий код, чтобы создать модель AllNotesPage с именем AllNotes:

    Замечание

    Чтобы ссылаться на класс AllNotes, необходимо добавить using WinUINotes.Models; в верхней части файла.

    public sealed partial class AllNotesPage : Page
    {
        // ↓ Add this. ↓
        private AllNotes notesModel = new AllNotes();
        // ↑ Add this. ↑
    
        public AllNotesPage()
        {
            this.InitializeComponent();
        }
    }
    

Проектирование страницы AllNotes

Затем необходимо разработать представление для поддержки модели AllNotes.

  1. В области Обозреватель решений откройте файл Views\AllNotesPage.xaml.

  2. Замените <Grid> ... </Grid> элемент следующей разметкой:

    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
    
        <CommandBar DefaultLabelPosition="Right">
            <AppBarButton Icon="Add" Label="New note"/>
            <CommandBar.Content>
                <TextBlock Text="Quick notes" Margin="16,8" 
                       Style="{ThemeResource SubtitleTextBlockStyle}"/>
            </CommandBar.Content>
        </CommandBar>
    
        <ItemsView ItemsSource="{x:Bind notesModel.Notes}" 
               Grid.Row="1" Padding="16" >
            <ItemsView.Layout>
                <UniformGridLayout MinItemWidth="200"
                               MinColumnSpacing="12"
                               MinRowSpacing="12"
                               ItemsJustification="Start"/>
            </ItemsView.Layout>
        </ItemsView>
    </Grid>
    

В предыдущем XAML представлены несколько новых концепций:

  • Элемент управления CommandBar содержит AppBarButton. Эта кнопка имеет Label и Icon, и находится под влиянием CommandBar, который её содержит. Например, это CommandBar задает положение метки для кнопок Right. Панели команд обычно отображаются в верхней части приложения вместе с заголовком страницы.
  • Элемент управления ItemsView отображает коллекцию элементов, и в данном случае привязан к свойству модели Notes . Способ отображения элементов в представлении определяется свойством ItemsView.Layout. Здесь вы используете UniformGridLayout.

Теперь, когда вы создали AllNotesPage, необходимо обновить MainWindow.xaml в последний раз, чтобы он загружал AllNotesPage вместо отдельного NotePage.

  1. В области Обозреватель решений откройте файл MainWindow.xaml.

  2. Обновите rootFrame элемент так, чтобы SourcePageType указывал на views.AllNotesPage, как здесь:

    <Frame x:Name="rootFrame" Grid.Row="1"
           SourcePageType="views:AllNotesPage"/>
    

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

Пользовательский интерфейс приложения заметок со списком заметок с именем класса Note вместо содержимого заметки.

Добавление шаблона данных

Необходимо указать DataTemplate , чтобы узнать, ItemsView как должен отображаться элемент данных. DataTemplate присваивается свойству ItemTemplate объекта ItemsView. Для каждого элемента в коллекции ItemsView.ItemTemplate создается указанный XAML.

  1. В области Обозреватель решений дважды щелкните запись AllNotesPage.xaml, чтобы открыть ее в редакторе XAML.

  2. Добавьте это новое сопоставление пространства имен в строке ниже сопоставления для local.

    xmlns:models="using:WinUINotes.Models"
    
  3. Добавьте элемент <Page.Resources> после открывающего тега <Page...>. Этот код извлекает ResourceDictionary из свойства PageResources, чтобы вы могли добавить в него ресурсы XAML.

    <Page
        x:Class="WinUINotes.Views.AllNotesPage"
        ... >
    <!-- ↓ Add this. ↓ -->
    <Page.Resources>
    
    </Page.Resources>
    
  4. Внутри элемента <Page.Resources> добавьте DataTemplate, который описывает, как отображать элемент Note.

    <Page.Resources>
        <!-- ↓ Add this. ↓ -->
        <DataTemplate x:Key="NoteItemTemplate" 
                      x:DataType="models:Note">
            <ItemContainer>
                <Grid Background="LightGray">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="120"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <TextBlock Text="{x:Bind Text}" Margin="12,8"
                               TextWrapping="Wrap"
                               TextTrimming="WordEllipsis"/>
                    <Border Grid.Row="1" Padding="8,6,0,6"
                            Background="Gray">
                        <TextBlock Text="{x:Bind Date}"
                                   Foreground="White"/>
                    </Border>
                </Grid>
            </ItemContainer>
        </DataTemplate>
        <!-- ↑ Add this. ↑ -->
    </Page.Resources>
    
  5. В XAML для ItemsView, измените Padding="16" на Margin="24" и назначьте свойство ItemTemplate только что созданному шаблону данных.

    <ItemsView ItemsSource="{x:Bind notesModel.Notes}"
               Grid.Row="1" Margin="24"
               <!-- ↓ Add this. ↓ -->
               ItemTemplate="{StaticResource NoteItemTemplate}">
    
  6. Создайте и запустите приложение.

При использовании расширения разметки x:Bind в объекте DataTemplate необходимо указать x:DataType на DataTemplate. В этом случае это отдельный элемент Note (поэтому необходимо добавить ссылку на пространство имен XAML для Models). Шаблон заметки использует два TextBlock элемента управления, которые привязаны к свойствам заметки Text и Date. Элемент Grid используется для макета и предоставляет цвет фона. Элемент Border используется для фона даты. (Элемент XAML Border может предоставлять как структуру, так и фон.)

При запуске приложения шаблон данных применяется к элементам Note и выглядит следующим образом, если в параметрах личной настройки Windows > используется светлый режим:

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

Однако если параметры Windows персонализации > цветов используют темный режим, он будет выглядеть следующим образом:

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

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

При определении ресурса в XAML ResourceDictionaryнеобходимо назначить x:Key значение для идентификации ресурса. Затем вы можете использовать это x:Key для получения ресурса в XAML с помощью расширений разметки {StaticResource} или {ThemeResource}.

  • Это {StaticResource} то же самое независимо от цветовой темы, поэтому он используется для таких вещей, как Font или Style параметры.
  • Элемент {ThemeResource} изменяется на основе выбранной цветовой темы, поэтому используется для Foreground, Background и других свойств, связанных с цветом.

WinUI включает в себя множество встроенных ресурсов, которые можно использовать, чтобы ваше приложение соответствовало рекомендациям по стилю Fluent, а также рекомендациям по доступности. Вы замените жёстко зафиксированные цвета в шаблоне данных встроенными ресурсами темы и примените несколько других ресурсов, чтобы соответствовать рекомендациям по проектированию в стиле Fluent Design.

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

    <DataTemplate x:Key="NoteItemTemplate" 
                  x:DataType="models:Note">
    
    <!-- ↓ Update this. ↓ -->
        <ItemContainer CornerRadius="{StaticResource OverlayCornerRadius}">
            <Grid Background="{ThemeResource CardBackgroundFillColorDefaultBrush}"
                  BorderThickness="1" 
                  BorderBrush="{ThemeResource CardStrokeColorDefaultBrush}"
                  CornerRadius="{StaticResource OverlayCornerRadius}">
    <!-- ↑ Update this. ↑ -->
    
                <Grid.RowDefinitions>
                    <RowDefinition Height="120"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <TextBlock Text="{x:Bind Text}" Margin="12,8"
                           TextWrapping="Wrap"
                           TextTrimming="WordEllipsis"/>
    
    <!-- ↓ Update this. ↓ -->
                <Border Grid.Row="1" Padding="8,6,0,6"
                        Background="{ThemeResource SubtleFillColorSecondaryBrush}">
                    <TextBlock Text="{x:Bind Date}"
                        Style="{StaticResource CaptionTextBlockStyle}"
                        Foreground="{ThemeResource TextFillColorSecondaryBrush}"/>
    <!-- ↑ Update this. ↑ -->
    
                </Border>
            </Grid>
        </ItemContainer>
    </DataTemplate>
    

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

Пользовательский интерфейс приложения заметок с легким фоном и шаблоном светлой заметки.

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

Пользовательский интерфейс приложения заметок с темным фоном и шаблоном темной заметки.

Дополнительные сведения см. в документации:

Подсказка

Приложение WinUI 3 Gallery — отличный способ узнать о различных элементах управления WinUI и рекомендациях по проектированию. Чтобы просмотреть ресурсы темы, используемые в шаблоне данных, откройте приложение WinUI 3 Gallery и перейдите к разделу "Руководство по цвету". Оттуда вы увидите, как выглядят ресурсы, и скопируйте необходимые значения непосредственно из приложения.

Вы также можете открыть страницу "Типография " и "Геометрия ", чтобы просмотреть другие встроенные ресурсы, используемые в этом шаблоне данных.

WinUI 3 Gallery Значок Приложение WinUI 3 Gallery включает интерактивные примеры элементов управления и функций WinUI. Получите приложение из Microsoft Store или просмотрите исходный код в GitHub.