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


Создание страницы для заметки

Теперь вы создадите страницу, которая позволяет пользователю изменять заметку, а затем вы напишете код для сохранения или удаления заметки.

Подсказка

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

Сначала добавьте новую страницу в проект:

  1. В области обозревателя решений Visual Studio щелкните правой кнопкой мыши на проекте WinUINotes и выберите Добавить>Новый элемент....

  2. В диалоговом окне "Добавление нового элемента" выберите WinUI в списке шаблонов в левой части окна. Затем выберите шаблон пустой страницы (WinUI). Присвойте файлу NotePage.xamlимя и нажмите кнопку "Добавить".

  3. Файл NotePage.xaml откроется на новой вкладке, отображая всю разметку XAML, представляющую пользовательский интерфейс страницы. Замените элемент <Grid> ... </Grid> в XAML на следующую разметку:

    <Grid Padding="16" RowSpacing="8">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="400"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
    
        <TextBox x:Name="NoteEditor"
             AcceptsReturn="True"
             TextWrapping="Wrap"
             PlaceholderText="Enter your note"
             Header="New note"
             ScrollViewer.VerticalScrollBarVisibility="Auto"
             Width="400"
             Grid.Column="1"/>
    
        <StackPanel Orientation="Horizontal"
                HorizontalAlignment="Right"
                Spacing="4"
                Grid.Row="1" Grid.Column="1">
            <Button Content="Save" Style="{StaticResource AccentButtonStyle}"/>
            <Button Content="Delete"/>
        </StackPanel>
    </Grid>
    
  4. Сохраните файл, нажав клавиши CTRL+S, щелкнув значок "Сохранить" на панели инструментов или выбрав в меню пункт Файл>Сохранить NotePage.xaml.

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

  5. Откройте MainWindow.xaml, и задайте NotePage в качестве SourcePageType на Frame, в следующем виде:

    <Frame x:Name="rootFrame" Grid.Row="1"
           SourcePageType="local:NotePage"/>
    

    Теперь, когда вы запускаете приложение, Frame загружает экземпляр NotePage и отображает его пользователю.

Это важно

Сопоставления пространства имен XAML (xmlns) являются аналогом XAML инструкции C# using . local: — это префикс, сопоставленный для вас на страницах XAML для проекта приложения (xmlns:local="using:WinUINotes"). Он сопоставляется с тем же пространством имен, которое создано для хранения x:Class атрибута и кода для всех файлов XAML, включая App.xaml. Если вы определяете любые пользовательские классы, которые вы хотите использовать в XAML в этом же пространстве имен, можно использовать local: префикс для ссылки на пользовательские типы в XAML.

Давайте разберем ключевые части элементов управления XAML, размещенные на странице:

Новый пользовательский интерфейс страницы заметок с сеткой, выделенной Visual Studio.

  • Grid.RowDefinitions и Grid.ColumnDefinitions определяют сетку с 2 строками и 3 столбцами (помещенными под строкой заголовка).

    • Нижняя строка автоматически изменяет размер под своё содержимое, две кнопки. Верхняя строка использует все оставшееся вертикальное пространство (*).
    • Средний столбец имеет 400ширину epx и находится в том месте, где идет редактор заметок. Столбцы по обеим сторонам пусты и разделяют все оставшееся горизонтальное пространство между ними (*).

    Замечание

    Из-за того, как работает система масштабирования, при разработке приложения XAML вы работаете с эффективными пикселями, а не физическими пикселями. Эффективные пиксели (epx) — это виртуальная единица измерения, и они используются для выражения измерений макета и интервалов, независимо от плотности экрана.

  • <TextBox x:Name="NoteEditor" ... > ... </TextBox> — это элемент управления ввода текста (TextBox), настроенный для редактирования текста в нескольких строках, и помещается в ячейку верхней центральной части Grid (Grid.Column="1"). Индексы строк и столбцов основаны на 0, и по умолчанию элементы управления помещаются в строку 0 и столбец 0 родительского элемента Grid. Таким образом, это эквивалент указания строки 0, столбца 1.

  • <StackPanel Orientation="Horizontal" ... > ... </StackPanel> определяет элемент управления макетом (StackPanel), который располагает дочерние элементы по вертикали (по умолчанию) или горизонтально. Он помещается в нижнюю центральную ячейку Grid (Grid.Row="1" Grid.Column="1").

    Замечание

    Grid.Row="1" Grid.Column="1" — это пример присоединённых свойств XAML. Присоединенные свойства позволяют одному объекту XAML задать свойство, которое принадлежит другому объекту XAML. Часто дочерние элементы могут использовать присоединенные свойства для информирования родительского элемента о том, как они должны быть представлены в пользовательском интерфейсе.

  • Два <Button> элемента управления находятся внутри <StackPanel> и упорядочены по горизонтали. Вы добавите код для обработки событий нажатия кнопки в следующем разделе.

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

Загрузка и сохранение заметки

NotePage.xaml.cs Откройте файл программной части. При добавлении нового XAML-файла программный код содержит одну строку в конструкторе: вызов метода InitializeComponent.

namespace WinUINotes
{
    public sealed partial class NotePage : Page
    {
        public NotePage()
        {
            this.InitializeComponent();
        }
    }
}

Метод InitializeComponent считывает разметку XAML и инициализирует все объекты, определенные разметкой. Объекты связаны в иерархических отношениях родитель-потомок, а обработчики событий, определенные в коде, подключены к событиям, определённым в XAML.

Теперь вы добавите код в NotePage.xaml.cs файл программной части для обработки загрузки и сохранения заметок.

  1. Добавьте следующие объявления переменных в класс NotePage:

    public sealed partial class NotePage : Page
    {
        private StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        private StorageFile? noteFile = null;
        private string fileName = "note.txt";
    

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

    Класс StorageFolder используется для доступа к локальной папке данных приложения. Эта папка связана с приложением, поэтому заметки, сохраненные здесь, не могут быть доступны другим приложениям. Класс StorageFile используется для доступа к текстовому файлу, сохраненном в этой папке. Имя файла представлено переменной fileName . Теперь задайте fileName на "note.txt".

  2. Создайте обработчик событий для события loaded страницы заметок.

    public NotePage()
    {
        this.InitializeComponent();
        // ↓ Add this. ↓
        Loaded += NotePage_Loaded;
    }
    
    // ↓ Add this event handler method. ↓
    private async void NotePage_Loaded(object sender, RoutedEventArgs e)
    {
        noteFile = (StorageFile)await storageFolder.TryGetItemAsync(fileName);
        if (noteFile is not null)
        {
            NoteEditor.Text = await FileIO.ReadTextAsync(noteFile);
        }
    }
    

    В этом методе вызывается TryGetItemAsync , чтобы получить текстовый файл из папки. Если файл не существует, он возвращается null. Если файл существует, вызовите ReadTextAsync , чтобы считывать текст из файла в NoteEditor свойство Text элемента управления. (Помните, что NoteEditor - это элемент управления, который вы создали с помощью TextBox в XAML-файле. Вы ссылаетесь на него в файле с кодом, используя назначенный ему x:Name.)

    Это важно

    Этот метод необходимо пометить ключевым async словом, так как вызовы доступа к файлам являются асинхронными. Короче говоря, при вызове метода, заканчивающегося ...Async (например TryGetItemAsync), можно добавить оператор await в вызов. Это предотвращает выполнение последующего кода до завершения ожидаемого вызова и сохраняет отзывчивость вашего пользовательского интерфейса. При использовании await, метод, который вы вызываете, необходимо пометить ключевым словом async. Дополнительные сведения см. в статье "Вызов асинхронных API" в C#.

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

Добавление обработчиков событий

Затем добавьте обработчики событий Click для кнопок "Сохранить и удалить". Добавление обработчиков событий — это то, что вы будете делать часто при создании приложений, поэтому Visual Studio предоставляет несколько функций, чтобы упростить работу.

  1. В файле NotePage.xaml поместите курсор после атрибута Content в элементе управления СохранитьButton. Введите Click=. На этом этапе в Visual Studio должен появиться интерфейс автозавершения, который выглядит следующим образом:

    Снимок экрана: новый обработчик событий Visual Studio автоматически завершает пользовательский интерфейс в редакторе XAML

    • Нажмите клавишу СТРЕЛКА ВНИЗ, чтобы выбрать <новый обработчик> событий, а затем нажмите клавишу TAB. Visual Studio завершит атрибут и Click="Button_Click" добавит метод обработчика событий, названный Button_Click в файле кода программной NotePage.xaml.cs части.

    Теперь вы должны переименовать метод Button_Click на более осмысленное название. Это будет выполняться в следующих шагах.

  2. В NotePage.xaml.csнайдите метод, который был добавлен для вас:

    private void Button_Click(object sender, RoutedEventArgs e)
    {
    
    }
    

    Подсказка

    Чтобы найти код в приложении, щелкните "Поиск " в строке заголовка Visual Studio и используйте параметр "Поиск кода ". Дважды щелкните результат поиска, чтобы открыть код в редакторе кода.

    Функция поиска в Visual Studio

  3. Поместите курсор перед "B" в Button и введите Save. Подождите момент, и имя метода будет выделено зеленым цветом.

  4. При наведении указателя мыши на имя метода Visual Studio отобразит подсказку со значком отвертки или лампочки. Нажмите кнопку со стрелкой вниз рядом со значком, а затем нажмите Переименовать "Button_Click" в "SaveButton_Click".

    Пользовательский интерфейс всплывающего окна переименования метода в Visual Studio.

    Visual Studio переименовывает метод везде в вашем приложении, включая XAML-файл, в который вы сначала добавили его в Button.

  5. Повторите эти действия для кнопки Delete и переименуйте метод DeleteButton_Clickв .

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

  1. Добавьте этот код в SaveButton_Click метод для сохранения файла. Обратите внимание, что также необходимо обновить сигнатуру метода с помощью ключевого async слова.

    private async void SaveButton_Click(object sender, RoutedEventArgs e)
    {
        if (noteFile is null)
        {
            noteFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
        }
        await FileIO.WriteTextAsync(noteFile, NoteEditor.Text);
    }
    

    В методе SaveButton_Click сначала проверьте, был ли создан noteFile. Если это null, необходимо создать новый файл в локальной папке хранения с именем, представленным переменной fileName, и присвоить этот файл переменной noteFile. Затем вы записываете текст в элемент управления TextBox, в файл, представленный noteFile.

  2. Добавьте этот код в DeleteButton_Click метод для удаления файла. Здесь также необходимо обновить сигнатуру метода с async ключевым словом.

    private async void DeleteButton_Click(object sender, RoutedEventArgs e)
    {
        if (noteFile is not null)
        {
            await noteFile.DeleteAsync();
            noteFile = null;
            NoteEditor.Text = string.Empty;
        }
    }
    

    В методе DeleteButton_Click сначала проверяется, существует ли noteFile. При этом удалите файл, представленный noteFile из локальной папки хранилища, и задайте для него значениеnoteFilenull. Затем сбросьте текст в элементе управления TextBox на пустую строку.

    Это важно

    После удаления текстового файла из файловой системы важно задать значение noteFilenull. Помните, что noteFile это StorageFile , предоставляющий доступ к системным файлам в приложении. После удаления noteFile системного файла по-прежнему указывает на то, где находится системный файл, но не знает, что он больше не существует. Если вы пытаетесь прочитать, написать или удалить системный файл сейчас, вы получите ошибку.

  3. Сохраните файл, нажав клавиши CTRL+S, щелкнув значок "Сохранить" на панели инструментов или выбрав в меню пункт Файл>Сохранить NotePage.xaml.cs.

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

using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Controls;
using System;
using Windows.Storage;

namespace WinUINotes
{
    public sealed partial class NotePage : Page
    {
        private StorageFolder storageFolder = ApplicationData.Current.LocalFolder;
        private StorageFile? noteFile = null;
        private string fileName = "note.txt";

        public NotePage()
        {
            this.InitializeComponent();
            Loaded += NotePage_Loaded;
        }

        private async void NotePage_Loaded(object sender, RoutedEventArgs e)
        {
            noteFile = (StorageFile)await storageFolder.TryGetItemAsync(fileName);
            if (noteFile is not null)
            {
                NoteEditor.Text = await FileIO.ReadTextAsync(noteFile);
            }
        }

        private async void SaveButton_Click(object sender, RoutedEventArgs e)
        {
            if (noteFile is null)
            {
                noteFile = await storageFolder.CreateFileAsync(fileName, CreationCollisionOption.ReplaceExisting);
            }
            await FileIO.WriteTextAsync(noteFile, NoteEditor.Text);
        }

        private async void DeleteButton_Click(object sender, RoutedEventArgs e)
        {
            if (noteFile is not null)
            {
                await noteFile.DeleteAsync();
                noteFile = null;
                NoteEditor.Text = string.Empty;
            }
        }
    }
}

Проверка заметки

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

  1. Создайте и запустите проект, нажав клавишу F5, нажав кнопку отладки "Пуск" на панели инструментов или выбрав меню Запустить>отладку.
  2. Введите текст в текстовое поле и нажмите кнопку "Сохранить ".
  3. Закройте приложение, а затем перезапустите его. Введенное примечание должно быть загружено из хранилища устройства.
  4. Нажмите кнопку "Удалить ".
  5. Закройте приложение, перезапустите его. У вас должна появиться новая пустая заметка.

Это важно

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