SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

Windowsで進化するマルチプラットフォームGUI開発

マルチプラットフォームのGUIフレームワーク「Avalonia UI」でMVVMアプリを始めよう

Windowsで進化するマルチプラットフォームGUI開発 第5回

  • X ポスト
  • このエントリーをはてなブックマークに追加

予測気温表示アプリ

 ここからは、県庁所在地の予測気温を表示するアプリを作成します。県庁所在地を選ぶと、現在時から24時間先までの予測気温を表示します。予測気温のデータは、Open MeteoのWebAPIを利用します。また、県庁所在地の情報は「都道府県庁所在地 緯度経度データ」で公開されているものを使用しました。

予測気温表示アプリ
予測気温表示アプリ

県庁所在地と位置のモデルクラス

 県庁所在地を選択するにはコンボボックスを使用するのですが、そのコンボボックスの選択肢となるデータはアプリの起動時にCSVファイルから読み込む形にしました。

 県庁所在地のCSVファイルは公開されているものを少し加工し、次のようにしました。

[リスト3]capitallatlon.csv
1,北海道,札幌市,43.06417,141.34694
2,青森県,青森市,40.82444,140.74
~略~
47,沖縄県,那覇市,26.2125,127.68111

 文字コードをUTF-8として保存し、プロジェクトフォルダにコピーしておきます。そして、ファイルのプロパティにある「出力ディレクトリにコピー」という項目を「新しい場合はコピーする」にしておきます。

CSVファイル
CSVファイル

 CSVファイルの各行は、連番、都道府県名、県庁所在地、緯度、経度になっています。まずは、このデータを保持するモデルクラスを作っていきます。

 1つの県庁所在地と位置を表すモデルクラス(CapitalPoint)とCapitalPointオブジェクトのコレクションを保持するクラス(CapitalList)を次のようにしました。

[リスト4]CapitalPoint.cs
public class CapitalPoint
{
    public string Name { get; init; } = string.Empty; // 県庁所在地
    public double Lat { get; init; }                  // 緯度
    public double Lon { get; init; }                  // 経度
}
[リスト5]CapitalList.cs
public class CapitalList
{
    // 県庁所在地のリスト
    public List<CapitalPoint> Capitals { get; } = new();

~中略~
}

 これらのクラスは、プロジェクトのModelフォルダに作成します。

CSVファイルの読み込み

 CapitalListクラスでは、コンストラクトでCSVファイルを読み込むようにしました。

[リスト6]CapitalList.cs
public class CapitalList
{
~中略~
    // 県庁所在地のCSVファイルから、県庁所在地名と緯度経度を読み込む
    public CapitalList(string filePath)
    {
        try
        {
            foreach (var line in File.ReadAllLines(filePath))
            {
                var items = line.Split(',');
                var pt = new CapitalPoint()
                {
                    Name = items[1] + items[2],     // 都道府県名県庁所在地
                    Lat = Double.Parse(items[3]),   // 緯度
                    Lon = Double.Parse(items[4])    // 経度
                };
                Capitals.Add(pt);
            }
        }
~中略~
    }
}

 C#でCSVファイルを読み込む方法はいくつかありますが、今回はFile.ReadAllLinesメソッドを用いてファイル内容をいったんすべて文字列配列に読み込み、その後に処理するようにしました。

 CSVファイルには、ヘッダー行の有無や項目をダブルクォーテーションで囲むなど、仕様の幅があります。今回はごくシンプルなCSVファイルなので、読み込む処理もシンプルです。各行の文字列をSplitメソッドで分割し、CapitalPointオブジェクトを作ってListコレクションに追加しています。

ビューモデルとビュー

 次に、この県庁所在地リストをコンボボックスで表示してみましょう。まずは、ビューモデル(MainWindowViewModel)に県庁所在地と県庁所在地リストを参照するプロパティを追加します(Greetingプロパティは削除します)。

[リスト7]MainWindowViewModel.cs
public class MainWindowViewModel : ViewModelBase
{
    // 県庁所在地
    public CapitalPoint Capitalpoint { get; init; } = new();

    // 県庁所在地のリスト
    public IEnumerable<CapitalPoint> Capitals { get; }

    public MainWindowViewModel(string filePath)
    {
        Capitals = new CapitalList(filePath).Capitals;
    }
~中略~
}

 MainWindowViewModelのコンストラクタを少し変更して、引数でCSVファイルのパス名を渡すようにしています。

 ビューのMainWindow.axamlには、UI要素のコンボボックス<ComboBox>を追加します。

[リスト8]MainWindow.axaml
<StackPanel HorizontalAlignment="Center">
    <ComboBox HorizontalAlignment="Center" Margin="0,10,0,0" Name="capitalComboBox" Items="{Binding Capitals}"  SelectedItem="{Binding Capitalpoint}">
       <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding Name}" />
            </DataTemplate>
        </ComboBox.ItemTemplate>
    </ComboBox>
</StackPanel>

 <StackPanel>は、複数のUIパーツを並べる枠のようなものです。ここではHorizontalAlignment属性にCenterを指定して、画面の水平位置の中央に表示されるようにしています。<StackPanel>内のUIパーツは、デフォルトでは縦に並びます。各UIパーツは、マージン(間隔)をMargin属性で、左、上、右、下の順にカンマ区切りで指定します。

 <StackPanel>のなかに、まずは<ComboBox>を配置します。<ComboBox>のItems属性でコンボボックスの選択肢リストであるCapitalsプロパティをバインディングし、SelectedItem属性でCapitalpointプロパティをバインディングしています。コンボボックスの選択肢リストの表示は<ComboBox.ItemTemplate>で指定します。今回はテキストのみの表示なので、<TextBlock>を配置し、Nameプロパティを指定しています。このNameプロパティは、CapitalPointオブジェクトのNameプロパティのことです。

 なお、Avalonia UIで利用できるUIパーツ(コントロール)には、次のようなものがあります。

UIコントロール
UIコントロール

 現状では、Visual Studio利用時、WPFのようなドラッグ&ドロップでUIがデザインできるようにはなっていません。一応プレビューには対応しているのですが、うまく表示されない場合もあります。このあたりは発展途上でしょう。

コンボボックスの表示

 今回は、MainWindowViewModelクラスのコンストラクタでCSVファイルのパス名を指定するように変更しました。そのため、MainWindowViewModelクラスを生成している箇所も変更が必要です。App.axaml.csにアプリケーションクラスの定義があり、そのなかのOnFrameworkInitializationCompletedメソッドのなかでMainWindowViewModelオブジェクトを生成し、DataContextプロパティに設定しています。ここで、パス名を指定するようにします。DataContextプロパティは、ビュー(MainWindow)に関連づけるビューモデル(MainWindowViewModel)を指定するものです。

[リスト9]App.axaml.cs
~中略~
public partial class App : Application
{
    public override void OnFrameworkInitializationCompleted()
    {
~中略~
        desktop.MainWindow = new MainWindow
        {
            // CSVファイルを指定して生成する
            DataContext = new MainWindowViewModel("capitallatlon.csv"),
        };
~中略~
    }
}

 ここまでで、アプリを起動してみましょう。画面中央にコンボボックスが表示され、県庁所在地が選択できるようになっているはずです。

コンボボックスの表示
コンボボックスの表示

最後に

 今回はAvalonia UIを紹介しました。Avalonia UIはWPFに似たフレームワークですが、Windowsだけではなく.NETが動作する幅広い環境で利用できます。ただ、どちらかと言えばデスクトップ環境向けのフレームワークでしょう。

 次回は今回のアプリの残り、ボタン処理やWebAPIの処理などを解説する予定です。

参考文献

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
Windowsで進化するマルチプラットフォームGUI開発連載記事一覧

もっと読む

この記事の著者

WINGSプロジェクト 高江 賢(タカエ ケン)

WINGSプロジェクトについて>有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂きたい。著書記事多数。 RSS X: @WingsPro_info(公式)、@WingsPro_info/wings(メンバーリスト) Facebook

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

山田 祥寛(ヤマダ ヨシヒロ)

静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for Visual Studio and Development Technologies。執筆コミュニティ「WINGSプロジェクト」代表。主な著書に「独習シリーズ(Java・C#・Python・PHP・Ruby・JSP&サーブレットなど)」「速習シリーズ(ASP.NET Core・Vue.js・React・TypeScript・ECMAScript、Laravelなど)」「改訂3版JavaScript本格入門」「これからはじめるReact実践入門」「はじめてのAndroidアプリ開発 Kotlin編 」他、著書多数

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/17163 2023/01/18 11:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング