LoginSignup
17
15

More than 3 years have passed since last update.

Windows GUIプログラミング入門13 リストビュー(2)、メニュー

Last updated at Posted at 2017-04-09

■はじめに

前回に引き続き、ListViewを使います。
今回はCSVを読み込ませてListViewに表示します。

キーワード:ListView, Menu, OpenFileDialog, CSV

[注意]
これまでの回で説明済みの操作方法等は、説明を省略したり簡略化している場合があります。

■開発環境

  • Windows 10 (バージョン1703)
  • Visual Studio Community 2017
  • .NET Framework 4.x

■作ってみる

◇CSVデータ

郵便番号のCSVデータをListViewに表示するプログラムを作ります。
今回使うデータはこちら。
郵便番号データダウンロード - 日本郵便
CSVデータの仕様はこちら。
郵便番号データの説明 - 日本郵便

プロジェクトにクラスを追加します。
名前はZipRecord.csにします。
これがCSV1件分に対応します。

ZipRecord.cs
/// <summary>
/// 郵便番号データ
/// </summary>
public class ZipRecord
{
    /// <summary>
    /// 全国地方公共団体コード
    /// </summary>
    public string Code { get; set; }

    /// <summary>
    /// (旧)郵便番号
    /// </summary>
    public string ZipOld { get; set; }

    /// <summary>
    /// 郵便番号
    /// </summary>
    public string Zip { get; set; }

    /// <summary>
    /// 都道府県名カナ
    /// </summary>
    public string StateKana { get; set; }

    /// <summary>
    /// 市区町村名カナ
    /// </summary>
    public string CityKana { get; set; }

    /// <summary>
    /// 町域名カナ
    /// </summary>
    public string TownKana { get; set; }

    /// <summary>
    /// 都道府県名
    /// </summary>
    public string State { get; set; }

    /// <summary>
    /// 市区町村名
    /// </summary>
    public string City { get; set; }

    /// <summary>
    /// 町域名
    /// </summary>
    public string Town { get; set; }

    /// <summary>
    /// 一町域が二以上の郵便番号で表される場合の表示
    /// </summary>
    /// <remarks>
    /// 「1」は該当、「0」は該当せず
    /// </remarks>
    public string Flag1 { get; set; }

    /// <summary>
    /// 小字毎に番地が起番されている町域の表示
    /// </summary>
    /// <remarks>
    /// 「1」は該当、「0」は該当せず
    /// </remarks>
    public string Flag2 { get; set; }

    /// <summary>
    /// 丁目を有する町域の場合の表示
    /// </summary>
    /// <remarks>
    /// 「1」は該当、「0」は該当せず
    /// </remarks>
    public string Flag3 { get; set; }

    /// <summary>
    /// 一つの郵便番号で二以上の町域を表す場合の表示
    /// </summary>
    /// <remarks>
    /// 「1」は該当、「0」は該当せず
    /// </remarks>
    public string Flag4 { get; set; }

    /// <summary>
    /// 更新の表示
    /// </summary>
    /// <remarks>
    /// 「0」は変更なし、「1」は変更あり、「2」廃止(廃止データのみ使用)
    /// </remarks>
    public string Flag5 { get; set; }

    /// <summary>
    /// 変更理由
    /// </summary>
    /// <remarks>
    /// 「0」は変更なし、「1」市政・区政・町政・分区・政令指定都市施行、
    /// 「2」住居表示の実施、「3」区画整理、「4」郵便区調整等、
    /// 「5」訂正、「6」廃止(廃止データのみ使用)
    /// </remarks>
    public string Flag6 { get; set; }
}

◇メニュー・リストビュー

Gridを真ん中ぐらいで分割して上の段にMenuを、下の段にListViewを配置します。
wbg13-01.png

Menuのプロパティ、Itemsの「...」からコレクションエディターを表示します。
wbg13-02.png

MenuItemを2つ作ります。
1つ目のHeaderは「ファイル(_F)」、2つ目は「編集(_E)」にします。
wbg13-03.png

追加後。
wbg13-04.png

「ファイル」のMenuItemを選択し、Itemsのコレクションエディターを開きます。
wbg13-05.png

MenuItemで「開く(_O)...」、
Separator
MenuItemで「終了(_X)」を追加します。
wbg13-06.png

追加後。
wbg13-07.png

「編集」メニューを選択し、今度は「MenuItemの追加」で項目を追加します。
wbg13-08.png

Headerは「クリア(_C)」にします。
wbg13-09.png

「開く」メニューに名前を付けます。
wbg13-10.png

openMenuにします。
wbg13-11.png

同様に「終了」メニューはexitMenuに、「クリア」メニューはclearMenuにします。

<MenuItem Header="ファイル(_F)">
    <MenuItem x:Name="openMenu" Header="開く(_O)..."/>
    <Separator/>
    <MenuItem x:Name="exitMenu" Header="終了(_X)"/>
</MenuItem>
<MenuItem Header="編集(_E)">
    <MenuItem x:Name="clearMenu" Header="クリア(_C)"/>
</MenuItem>

デザイナでGridの上段をAutoに、下段をStarに設定(やり方は第5回参照)し、
MenuListViewのレイアウトを「すべてリセット」(やり方は第7回参照)します。

◇ウィンドウ

WindowTitle郵便番号一覧に、ResizeModeCanResizeWithGripに設定します。
wbg13-12.png

◇表示とデータの関連付け

ListViewとCSVデータの入れ物を関連付けます。

MainWindow.xaml.cs
public partial class MainWindow : Window
{
    // 郵便番号データのコレクション
    public System.Collections.ObjectModel.ObservableCollection<ZipRecord> ZipRecords { get; set; }

    /// <summary>
    /// コンストラクタ
    /// </summary>
    public MainWindow()
    {
        InitializeComponent();

        // 郵便番号データのコレクションを初期化
        this.ZipRecords = new System.Collections.ObjectModel.ObservableCollection<ZipRecord>();
        // 関連付け
        listView.DataContext = this.ZipRecords;
    }
}

XamlでListViewを選択し、プロパティのItemsSource横のメニューから「データバインドの作成」を選択し、「バインドの種類」に「データコンテキスト」を選択します。

◇リストビューの列

ListViewの列を設定します。

ListViewColumnsのコレクションエディターを開きます。
wbg13-13.png

GridViewColumnsを以下のように設定します。

DisplayMemberBinding Header
Zip 郵便番号
State 都道府県名
City 市区町村名
CityKana 市区町村名カナ
Town 町域名
TownKana 町域名カナ

DisplayMemberBindingは横のメニューから「データバインドの作成」を選択し、
wbg13-14.png

「バインドの種類」に「データコンテキスト」を選択し、「パス」の欄に表示元データ(ZipRecordクラス)の項目名を入力します。
wbg13-15.png

ここまででListViewは以下のようになります。

<ListView x:Name="listView" Grid.Row="1" ItemsSource="{Binding Mode=OneWay}">
    <ListView.View>
        <GridView>
            <GridViewColumn DisplayMemberBinding="{Binding Zip}" Header="郵便番号"/>
            <GridViewColumn DisplayMemberBinding="{Binding State}" Header="都道府県名"/>
            <GridViewColumn DisplayMemberBinding="{Binding City}" Header="市区町村名"/>
            <GridViewColumn DisplayMemberBinding="{Binding CityKana}" Header="市区町村名カナ"/>
            <GridViewColumn DisplayMemberBinding="{Binding Town}" Header="町域名"/>
            <GridViewColumn DisplayMemberBinding="{Binding TownKana}" Header="町域名カナ"/>
        </GridView>
    </ListView.View>
</ListView>

wbg13-16.png

◇CSV読み込み

CSV読み込みの機能を使うために、参照の追加でMicrosoft.VisualBasicを追加します。

コードビハインドにCSVを読み込むメソッドを作ります。

MainWindow.xaml.cs
/// <summary>
/// CSVファイル読み込み
/// </summary>
/// <param name="filePath">CSVファイルパス</param>
private void ReadCsv(string filePath)
{
    this.ZipRecords.Clear();

    var parser =
        new Microsoft.VisualBasic.FileIO.TextFieldParser(filePath, Encoding.Default);
    using (parser)
    {
        // 「,」区切りのデータとして処理する
        parser.TextFieldType = Microsoft.VisualBasic.FileIO.FieldType.Delimited;
        parser.SetDelimiters(",");

        try
        {
            // ファイルの終わりまで繰り返す
            while (parser.EndOfData == false)
            {
                // 一行分読み込み
                string[] buf = parser.ReadFields();

                this.ZipRecords.Add(new ZipRecord
                {
                    Code = buf[0],
                    ZipOld = buf[1],
                    Zip = buf[2],
                    StateKana = buf[3],
                    CityKana = buf[4],
                    TownKana = buf[5],
                    State = buf[6],
                    City = buf[7],
                    Town = buf[8],
                    Flag1 = buf[9],
                    Flag2 = buf[10],
                    Flag3 = buf[11],
                    Flag4 = buf[12],
                    Flag5 = buf[13],
                    Flag6 = buf[14],
                });

            }
        }
        catch
        {
            throw new Exception("CSV読み込みでエラー!");
        }
    }
}

◇ファイルを開く

メニューから「開く」を選択した時の処理を作ります。
ドキュメントアウトラインで「openMenu」を選択し、画面の「開く」メニューをダブルクリックし、以下を入力します。
wbg13-17.png

/// <summary>
/// メニュー「開く」
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void openMenu_Click(object sender, RoutedEventArgs e)
{
    var dlg = new Microsoft.Win32.OpenFileDialog();

    // フィルタ設定
    dlg.Filter = "CSVファイル(*.csv)|*.csv|テキストファイル(*.txt)|*.txt|全てのファイル(*.*)|*.*";
    // フィルタの1番目(CSV)を選択状態にする
    dlg.FilterIndex = 1;

    // ファイルを開くダイアログ表示
    if (dlg.ShowDialog() == true)
    {
        this.IsEnabled = false;

        // CSV読み込み
        ReadCsv(dlg.FileName);

        this.IsEnabled = true;
    }
}

◇その他のメニュー処理

メニュー項目の「終了」、「クリア」も同様に処理を作ります。

/// <summary>
/// メニュー「終了」
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void exitMenu_Click(object sender, RoutedEventArgs e)
{
    // プログラム終了
    this.Close();
}

/// <summary>
/// メニュー「クリア」
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void clearMenu_Click(object sender, RoutedEventArgs e)
{
    // 一覧をクリア
    this.ZipRecords.Clear();
}

■動かしてみる

起動してみます。
wbg13-18.png

メニューの「ファイル」 - 「開く」でファイル選択ダイアログを表示します。
拡張子のフィルタの初期選択値はCSVになっています。
wbg13-19.png

こちらからダウンロードしたCSVを読み込ませてみます。
wbg13-20.png

表示されました。
wbg13-21.png

メニューの「編集」 - 「クリア」を選択すると一覧がクリアされ、「ファイル」 - 「終了」を選択するとプログラムが終了します。

おしまい

※次回はこのプログラムをもう少し改善します。まだ捨てないでください。


<< 最初の記事   < 前の記事   次の記事 >

17
15
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
15