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


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

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

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

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

  1. В области Обозреватель решений щелкните правой кнопкой мыши Views папку и выберите "Добавить>новый элемент".
  2. В диалоговом окне "Добавление нового элемента" выберите WinUI в списке шаблонов в левой части окна. Затем выберите шаблон пустой страницы (WinUI). Назовите файл AllNotesPage.xaml и нажмите клавишу Add.
  3. В области Обозреватель решений щелкните правой кнопкой мыши Models папку и выберите "Добавить>класс...
  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 метод для загрузки заметок из локального хранилища приложения.

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

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

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

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

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

    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 присваивается свойству ItemsTemplate у 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 назначьте свойство 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 адаптируются к тёмной или светлой цветовой предпочтительности пользователя. При определении собственных элементов, таких как шаблон данных, необходимо быть осторожным и применять ту же степень тщательности.

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

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

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