演習: 最初の XAML ページを作成する

完了

電力会社のエンジニアは、定期的に顧客を訪問し、アプライアンスを修理したり、その他の電気的メンテナンス作業を行ったりします。 エンジニアは、このアプリの一部で、訪問に関するメモを作成できます。 エンジニアが詳細を入力して保存できる、シンプルなエディターが表示されます。

Android では、アプリは次のように表示されます。

The engineer's app running on Android, showing the editor page.

あなたは、このページに、さらにいくつかの機能を追加するよう依頼されています。 開始する前に、このページがどのように作成されたかを理解する必要があるため、ソース コードを調べます。 UI がすべて C# コードを使用して作成されていることがわかります。 このアプローチは正しく機能していますが、レイアウトを処理するコードと、UI の動作方法を制御するコードが混在しています。 あなたは、やがてアプリの 2 つの側面が一緒に固定された状態となって、将来のメンテナンスが難しくなり、より多くの機能が追加されるにつれてアプリがより脆弱になる可能性があることを認識します。 レイアウトを定義している C# コードをアプリから取り出し、それを XAML ページに置き換えることで、UI デザインを UI ロジックから分離することに決めました。

このモジュールでは、.NET 8.0 SDK を使います。 適切なコマンド ターミナルで次のコマンドを実行して、.NET 8.0 がインストールされていることを確認します。

dotnet --list-sdks

次の例のような出力が表示されます。

6.0.317 [C:\Program Files\dotnet\sdk]
7.0.401 [C:\Program Files\dotnet\sdk]
8.0.100 [C:\Program Files\dotnet\sdk]

8 で始まるバージョンが一覧に表示されていることを確実にします。 何も表示されない場合、またはコマンドが見つからない場合は、最新の .NET 8.0 SDK をインストールしてください。

既存のアプリを調べる

  1. この演習用の GitHub リポジトリを、ローカルのコンピューターにクローンします。

    Note

    ビルドによって生成されたファイルが最大パス長を超えないようにするため、演習コンテンツを C:\dev などの短いフォルダー パスに複製またはダウンロードすることをお勧めします。

  2. リポジトリのローカル コピー内にある exercise1 フォルダーに移動します。

  3. このフォルダーまたは Visual Studio Code 内のフォルダーで Notes.sln Visual Studio ソリューション ファイルを開きます。

  4. ソリューション エクスプローラー ウィンドウで Notes プロジェクトを展開し、MainPage.xaml.cs ファイルを開きます。

  5. このファイルで定義されている MainPage クラスを調べます。 コンストラクターには、UI を作成する次のコードが含まれています。

    public MainPage()
    {
        var notesHeading = new Label() { Text = "Notes", HorizontalOptions = LayoutOptions.Center, FontAttributes = FontAttributes.Bold };
    
        editor = new Editor() { Placeholder = "Enter your note", HeightRequest = 100 };
        editor.Text = File.Exists(_fileName) ? File.ReadAllText(_fileName) : string.Empty;
    
        var buttonsGrid = new Grid() { HeightRequest = 40.0 };
        buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1.0, GridUnitType.Auto) });
        buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(30.0, GridUnitType.Absolute) });
        buttonsGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(1.0, GridUnitType.Auto) });
    
        var saveButton = new Button() { WidthRequest = 100, Text = "Save" };
        saveButton.Clicked += OnSaveButtonClicked;
        Grid.SetColumn(saveButton, 0);
        buttonsGrid.Children.Add(saveButton);
    
        var deleteButton = new Button() { WidthRequest = 100, Text = "Delete" };
        deleteButton.Clicked += OnDeleteButtonClicked;
        Grid.SetColumn(deleteButton, 2);
        buttonsGrid.Children.Add(deleteButton);
    
        var stackLayout = new VerticalStackLayout 
        { 
            Padding = new Thickness(30, 60, 30, 30),
            Children = { notesHeading, editor, buttonsGrid }
        };
    
        this.Content = stackLayout;
    }
    

    UI は、3 つの列で LabelEditorGrid を格納している VerticalStackLayout で構成されています。 最初の列は saveButton コントロールを保持していて、2 つ目の列はスペーサーです。そして 3 つ目の列には、deleteButton コントロールがあります。

    次の図に、UI の構造を示します。

    A diagram of the UI structure for the Notes app.

    MainPage クラスには、ボタン用のイベント処理メソッドと、Editor コントロールを初期化するコードも含まれていることに注意してください。 このコードは UI 定義と区別されていません。

  6. アプリの外観を確認するだけのために、Windows でアプリをビルドして実行します。 アプリをビルドして実行するには、F5 キーを選択します。

  7. 完了したら、アプリを閉じて、Visual Studio または Visual Studio Code に戻ります。

UI の XAML バージョンを作成する

  1. MainPage.xaml ファイルを開きます。 このページ内のマークアップは、空の MAUI コンテンツ ページを表しています。

    <ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
                 x:Class="Notes.MainPage">
    
    </ContentPage>
    
  2. このコンテンツ ページに VerticalStackLayout コントロールを追加します。

    <ContentPage ...>
        <VerticalStackLayout Margin="30,60,30,30">
    
        </VerticalStackLayout>
    </ContentPage>
    
  3. VerticalStackLayoutLabel コントロールを追加します。 次に示すように、このコントロールの TextHorizontalTextAlignmentFontAttributes プロパティを設定します。

    <ContentPage ...>
        <VerticalStackLayout ...>
            <Label Text="Notes"
                   HorizontalOptions="Center"
                   FontAttributes="Bold" />
        </VerticalStackLayout>
    </ContentPage>
    
  4. VerticalStackLayoutEditor コントロールを追加します。

    <ContentPage ...>
        <VerticalStackLayout ...>
            <Label .../>
    
            <Editor x:Name="editor"
                    Placeholder="Enter your note"
                    HeightRequest="100" />
        </VerticalStackLayout>
    </ContentPage>
    
  5. VerticalStackLayout に子の Grid を追加します。 この Grid には 3 つの列が必要です。1 列目と 3 列目は自動的にサイズ設定されますが、2 列目の幅は 30 です。

    <ContentPage ...>
        <VerticalStackLayout ...>
            <Label .../>
    
            <Editor .../>
    
            <Grid ColumnDefinitions="Auto, 30, Auto">
    
            </Grid>
        </VerticalStackLayout>
    </ContentPage>
    
  6. Grid の最初の列に Button を追加します。 これが [保存] ボタンです。

    <ContentPage ...>
        <VerticalStackLayout ...>
            <Label .../>
    
            <Editor .../>
    
            <Grid ...>                    
                <Button Grid.Column="0"
                        Text="Save" 
                        WidthRequest="100"
                        Clicked="OnSaveButtonClicked" />
            </Grid>
        </VerticalStackLayout>
    </ContentPage>
    
  7. Grid の 3 列目に別の Button を追加します。 これが [削除] ボタンです。

    <ContentPage ...>
        <VerticalStackLayout ...>
            <Label .../>
    
            <Editor .../>
    
            <Grid ...>                    
                <Button ... />
    
                <Button Grid.Column="2"
                        Text="Delete" 
                         WidthRequest="100"
                        Clicked="OnDeleteButtonClicked" />
            </Grid>
        </VerticalStackLayout>
    </ContentPage>
    

分離コード ファイルからレイアウト コードを削除する

  1. ソリューション エクスプローラー ウィンドウで MainPage.xaml ノードを展開し、MainPage.xaml.cs ファイルを開きます。

  2. MainPage クラスから Editor フィールドを削除します。

  3. MainPage.xaml.cs ファイルの MainPage コンストラクターで、ユーザー インターフェイス要素を作成するすべてのコードを削除し、それらを InitializeComponent メソッドの呼び出しに置き換えます。 メモの保存に使用されるファイルが存在するかどうかを確認し、ある場合は内容を読み取って Editor コントロールの Text フィールドにデータを格納するコードを追加します。 コンストラクターは、次のようになる必要があります。

    public partial class MainPage : ContentPage
    {
        string _fileName = Path.Combine(FileSystem.AppDataDirectory, "notes.txt");
    
        public MainPage()
        {
            InitializeComponent();
    
            if (File.Exists(_fileName))
            {
                editor.Text = File.ReadAllText(_fileName);
            }
        }
    
        ...
    }
    
  4. [ビルド] メニューで、[ソリューションのリビルド] を選択します。 まったくエラーなくアプリがビルドされることを確認します。

  5. アプリケーションを実行します。 これは以前とまったく同様に機能するはずです。

  6. 時間がある場合は、Android エミュレーターを使用してアプリをデプロイし、実行します。 アプリの UI は、この演習の開始時に画像で示したものと似ている必要があります。