次の方法で共有


メモのページを作成する

次に、ユーザーがメモを編集できるページを作成し、メモを保存または削除するコードを記述します。

ヒント

このチュートリアルのコードは 、GitHub リポジトリからダウンロードまたは表示できます。 この手順のコードをそのまま表示するには、コミット: メモ ページ - 初期を参照してください。

最初に、新しいページをプロジェクトに追加します。

  1. Visual Studio の ソリューション エクスプローラー ウィンドウで、 WinUINotes プロジェクト >Add>New Item... を右クリックします。

  2. [ 新しい項目の追加] ダイアログで、ウィンドウの左側にあるテンプレートの一覧で WinUI を選択します。 次に、 空白ページ (WinUI 3) テンプレートを選択します。 ファイルに NotePage.xaml名前を付け、[ 追加] を選択します。

  3. NotePage.xaml ファイルが新しいタブで開き、ページの UI を表す XAML マークアップがすべて表示されます。 XAML の <Grid> ... </Grid> 要素を次のマークアップに置き換えます。

    <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を選択して、ファイルを保存します。

    アプリを今すぐ実行すると、先ほど作成したノート ページは表示されません。 これは、FrameMainWindow コントロールのコンテンツとして設定する必要があるためです。

  5. MainWindow.xamlを開き、次のようにNotePageSourcePageType としてFrameを設定します。

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

    アプリを実行すると、 FrameNotePage のインスタンスを読み込み、ユーザーに表示します。

Important

XAML 名前空間 (xmlns) マッピング は、C# using ステートメントに対応する XAML です。 local: は、アプリ プロジェクト (xmlns:local="using:WinUINotes") の XAML ページ内でマップされるプレフィックスです。 x:Classを含むすべての XAML ファイルのApp.xaml属性とコードを含めるために作成されたのと同じ名前空間を参照するようにマップされます。 この同じ名前空間で XAML で使用するカスタム クラスを定義する限り、 local: プレフィックスを使用して XAML でカスタム型を参照できます。

以下でページに配置された XAML コントロールの主要なパーツを理解しましょう。

Visual Studio によってグリッドが強調表示された新しいノート ページ UI。

  • Grid.RowDefinitionsGrid.ColumnDefinitions では、2 行と 3 列 (タイトル バーの下に配置) のグリッドが定義されます。

    • 下部の行は、コンテンツ (2 つのボタン) に合わせて自動的にサイズ設定されます (Auto)。 上部の行では、残りの垂直スペース (*) がすべて使用されます。
    • 中央の列は 400ピクセル幅で、ノート エディターが移動する場所です。 両側の列は空で、残りの水平方向のスペース (*) をすべて分割します。

    スケーリング システムのしくみにより、XAML アプリを設計するときは、実際の物理ピクセルではなく、有効なピクセル単位で設計します。 有効ピクセル (epx) は仮想測定単位であり、画面密度に関係なく、レイアウトの寸法と間隔を表すために使用されます。

  • <TextBox x:Name="NoteEditor" ... > ... </TextBox> は、複数行のテキスト 入力用に構成されたテキスト 入力コントロール (TextBox) で、 Grid (Grid.Column="1") の上部中央のセルに配置されます。 行インデックスと列インデックスは 0 から始まります。既定では、コントロールは親 Gridの行 0 と列 0 に配置されます。 したがって、これは行 0、列 1 を指定することと同じです。

  • <StackPanel Orientation="Horizontal" ... > ... </StackPanel> は、その子を垂直方向 (既定) または水平方向にスタックするレイアウト コントロール (StackPanel) を定義します。 Gridの下部中央のセル (Grid.Row="1" Grid.Column="1") に配置されます。

    Grid.Row="1" Grid.Column="1" は、XAML 添付プロパティの例です。 添付プロパティを使用すると、1 つの XAML オブジェクトが別の XAML オブジェクトに属するプロパティを設定できます。 多くの場合、この場合と同様に、子要素は添付プロパティを使用して、UI での表示方法を親要素に通知できます。

  • 2 つの <Button> コントロールが <StackPanel> 内にあり、水平方向に配置されます。 次のセクションでは、ボタンの Click イベントを処理するコードを追加します。

詳細については、次のドキュメントを参照してください。

メモを読み込んで保存する

NotePage.xaml.cs分離コード ファイルを開きます。 新しい XAML ファイルを追加すると、コードビハインドは、コンストラクターに InitializeComponent メソッドの呼び出しという 1 行を含めます。

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 は、XAML ファイルで作成した TextBox コントロールです。ここには、割り当てた x:Name を使用して分離コード ファイルで参照します)。

    Important

    ファイル アクセス呼び出しは非同期であるため、このメソッドを async キーワードでマークする必要があります。 要するに、 ...Async で終わるメソッド ( TryGetItemAsyncなど) を呼び出す場合は、 await 演算子を呼び出しに追加できます。 これにより、待機中の呼び出しが完了するまで後続のコードが実行され、UI の応答性が維持されます。 awaitを使用する場合は、呼び出し元のメソッドを async キーワードでマークする必要があります。 詳細については、「 C# での非同期 API の呼び出し」を参照してください。

詳細については、次のドキュメントを参照してください。

イベント ハンドラーを追加する

次に、[保存] ボタンと [削除] ボタンの Click イベント ハンドラーを追加します。 イベント ハンドラーの追加は、アプリの作成中に頻繁に行う作業であるため、Visual Studio には、簡単にするためのいくつかの機能が用意されています。

  1. NotePage.xaml ファイルで、saveContent コントロールのButton属性の後にカーソルを置きます。 「Click=」と入力します。 この時点で、Visual Studio によって次のようなオートコンプリート UI がポップアップ表示されます。

    XAML エディターでの Visual Studio の新しいイベント ハンドラーの自動完了 UI のスクリーンショット

    • 下方向キーを押して <選択し> Tab キーを押します。Visual Studio は、を使用して属性を完成させ、Click="Button_Click"分離コード ファイルに Button_Click という名前のイベント ハンドラー メソッドを追加します。

    次に、 Button_Click メソッドの名前をより意味のある名前に変更する必要があります。 これを行うには、次の手順を実行します。

  2. NotePage.xaml.csで、追加されたメソッドを見つけます。

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

    ヒント

    アプリでコードを検索するには、Visual Studio タイトル バーの [ 検索 ] をクリックし、[ コード検索 ] オプションを使用します。 検索結果をダブルクリックして、コード エディターでコードを開きます。

    Visual Studio の検索機能

  3. Buttonの "B" の前にカーソルを置き、「Save」と入力します。 しばらく待つと、メソッド名が緑色で強調表示されます。

  4. メソッド名にカーソルを合わせると、Visual Studio にドライバーアイコンまたは電球アイコンが付いたヒントが表示されます。 アイコンの横にある下矢印ボタンをクリックし、[ Button_Click名の変更] を [SaveButton_Click] にクリックします。

    Visual Studio メソッドの名前を変更するポップアップ UI。

    Visual Studio では、最初に Buttonに追加した XAML ファイルを含め、アプリ内のあらゆる場所でメソッドの名前が変更されます。

  5. [削除] ボタンに対してこれらの手順を繰り返し、メソッドの名前を 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 コントロール内のテキストを空の文字列にリセットします。

    Important

    テキスト ファイルがファイル システムから削除されたら、 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. アプリを閉じて再起動します。 新しい空白のメモが表示されます。

Important

メモの保存と削除が正しく機能することを確認したら、新しいメモをもう一度作成して保存します。 後の手順でアプリをテストするために、保存したメモが必要になります。