【学習】WinFormsで作る天気チェッカー(クラスで整理する版)
これまでの学習では、
- List や Dictionary でデータを管理する
- ComboBox で選択する
- PictureBox で画像を表示する
という形でプログラムを動かしてきました。
しかし、都市名とAPI用コードのように関連するデータをまとめるには、クラスを使うと整理しやすくなります。
今回は クラス を使って、天気チェッカー を作ります。
今日作るもの
ComboBox で都道府県を選ぶと、
天気アイコンが PictureBox に表示されるという動きをします。例:東京都 を選択 → 東京の天気アイコンが表示されます。
前提
- WinForms の基本(フォーム、コントロール)を学んでいること
- ComboBox、PictureBox の使い方を知っていること
- クラスの基本(プロパティを持つクラスの定義)を学んでいること
ソリューションとプロジェクトを作る
- テンプレート: Windows Forms アプリ (.NET Framework)
- プロジェクト名: WeatherChecker
NuGet パッケージを追加する
天気APIのレスポンス(JSON)を扱うために Newtonsoft.Json をインストールします。
- ソリューションエクスプローラーでプロジェクトを右クリック → NuGet パッケージの管理
- 参照 タブで「Newtonsoft.Json」を検索
- Newtonsoft.Json を選択して インストール
フォームに配置するコントロール
フォームに次のものを配置します。
| コントロール | 名前 | 主な設定 |
|---|---|---|
| ComboBox | areaBox | 都道府県選択用 |
| PictureBox | weatherIcon | SizeMode = StretchImage |
| Label | label1 | Text = 都道府県を選択 |
| MenuStrip | menuStrip1 | メニューバー |
| ToolStripMenuItem | ファイルToolStripMenuItem | Text = ファイル |
| ToolStripMenuItem | 終了ToolStripMenuItem | Text = 終了 |
終了 メニューは ファイル の下にドロップダウンで配置します。
都市1件を表すクラス(CityInfo)
まず 都市1件 を表すクラスを作ります。名前とAPI用コードをまとめて持たせます。
CityInfo.cs をプロジェクトに追加し、次のコードを書きます。
class CityInfo
{
public string Name; // 表示名(例:東京都)
public string Code; // API用コード(例:3)
}天気情報を表すクラス(WeatherInfo)
API から返ってくる JSON の形をクラスで表します。今回は url(天気アイコンのURL)だけを使います。
WeatherInfo.cs をプロジェクトに追加し、次のコードを書きます。
using Newtonsoft.Json;
class WeatherInfo
{
[JsonProperty("url")]
public string Url { get; set; }
}[JsonProperty("url")] は、JSON の "url" というキーを Url プロパティに紐づける指定です。
イベントを登録する
- areaBox を選択 → プロパティウィンドウの イベント タブ → SelectedIndexChanged に
CitySelectedを登録 - 終了ToolStripMenuItem をダブルクリック →
ExitMenuClickedイベントが作成される
Form1.cs の完成コード
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Windows.Forms;
using Newtonsoft.Json;
namespace WeatherChecker
{
public partial class Form1 : Form
{
List<CityInfo> cities;
public Form1()
{
InitializeComponent();
cities = new List<CityInfo>
{
new CityInfo { Name = "東京都", Code = "3" },
new CityInfo { Name = "大阪府", Code = "1" },
new CityInfo { Name = "愛知県", Code = "2" },
new CityInfo { Name = "福岡県", Code = "10" }
};
foreach (var city in cities)
{
areaBox.Items.Add(city.Name);
}
}
private void CitySelected(object sender, EventArgs e)
{
string selectedName = areaBox.Text;
CityInfo city = FindCity(selectedName);
if (city == null) return;
// 天気APIのURL(学習用:実際のAPIに差し替えてください)
string url = $"https://example.com/api/weather?city={city.Code}";
string json = new HttpClient().GetStringAsync(url).Result;
WeatherInfo weather = JsonConvert.DeserializeObject<WeatherInfo>(json);
weatherIcon.ImageLocation = weather.Url;
}
private CityInfo FindCity(string name)
{
foreach (var c in cities)
{
if (c.Name == name) return c;
}
return null;
}
private void ExitMenuClicked(object sender, EventArgs e)
{
this.Close();
}
}
}プログラムの流れ
フォーム起動
↓
List<CityInfo> を初期化(4都市分)
↓
ComboBox に都市名を表示
↓
ユーザーが都市を選択
↓
CitySelected が呼ばれる
↓
FindCity で選択された都市の CityInfo を取得
↓
HttpClient で天気APIを呼び出し
↓
JSON を WeatherInfo にデシリアライズ
↓
PictureBox の ImageLocation にアイコンURLを設定クラスを使うメリット
Dictionary との違い
元のサンプルでは Dictionary<string, string> で都市名とコードを管理していました。
クラスにすると、
- CityInfo:都市名・コード以外に、緯度・経度などを後から追加しやすい
- WeatherInfo:天気の説明文や気温などを後から追加しやすい
- 型の安全性:プロパティ名を間違えるとコンパイル時に気づける
FindCity メソッド
FindCity で List から該当する都市を探しています。Dictionary なら cities[name] で一発ですが、List + クラス の形にすることで、クラスを使ったデータ管理の流れを学べます。
重要ポイント
- CityInfo:都市1件のデータをクラスでまとめる
- WeatherInfo:API レスポンスの形をクラスで表す
- List + クラス:拡張しやすいデータ管理
- JsonConvert.DeserializeObject:JSON をクラスに一括変換
- HttpClient:Web API からデータを取得
発展アイデア
- 天気の説明文や気温を
WeatherInfoに追加して表示する - 都市データを CSV や JSON ファイルから読み込む
async/awaitで非同期に API を呼び出し、UI が固まらないようにする
まとめ
今回学んだこと
- クラスで1件分のデータをまとめる(CityInfo、WeatherInfo)
- List で複数件を管理する
- HttpClient で Web API を呼び出す
- Newtonsoft.Json で JSON をクラスに変換する
- ComboBox の選択で PictureBox に画像を表示する
クラスを使うことで、データの形が整理され、将来の拡張も簡単になります。