【フォームアプリ】Controls(コレクション)でLINQを使う方法

2021年1月12日

Windowsフォームアプリケーションで、LINQを使ってまとめて処理する方法を見ていきましょう

ここでは、VisualStudioを使って、簡単なアプリケーションを作ったことがある方を対象にしています

次のようなデザインを作成します

フォームのデザイン

プロパティの設定

label1だけ、Nameをsampleとします。

あとは、自動作成のままにしておきます

ボタンクリックイベントの作成

button1 をダブルクリックして、ボタンクリックイベントを作成します。

Listを使って管理する場合

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ObjectListSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            List<Label> labels =new List<Label>{ sample, label2, label3 };

            foreach (Label label in labels)
            {
                label.Text = "abc";
            }
        }
    }
}

Controlsを使って管理する場合

フォームアプリでは、グループはコレクション(Controls)で管理されているので、それを利用します。

groupBox1のコンテナー内のオブジェクトを取得するには、groupBox1.Controlsで可能です。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ObjectListSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            foreach (Label label in groupBox1.Controls)
            {
                label.Text = "abc";
            }
        }
    }
}

実行してみて、動作を確認します。

Controlsはコレクションになります。foreach文で、処理することができます。

LINQを使ってデータを処理してみましょう

Controlsは直接LINQで操作できないため、Cast<コントロール>()で、変換する必要があります

Cast<コントロール>()以外に、OfType<コントロール>()を使っても構いません。

今回は、LINQを使って、全てのlabelのうちNameプロパティに文字列 (label) が含まれているものだけを抽出(フィルタ)します。そして、そのオブジェクトだけTextプロパティを文字列 (zzz) に変更してみます。(Containメソッドは、〜を含んでいるか?を検出し、boolで返すメソッドになります)

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ObjectListSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            var labelControls = groupBox1.Controls.Cast<Label>()
                                                  .Where(x => x.Name.Contains("label"));

            foreach (Label label in labelControls)
            {
                label.Text = "zzz";
            }
        }
    }
}

foreachも一緒にまとめると、

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ObjectListSample
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            groupBox1.Controls.Cast<Label>()
                              // Nameプロパティにlabelという文字列が含まれているものをフィルタ
                              .Where(x => x.Name.Contains("label”))
                              // Listに変換して
                              .ToList()
                              // foreachで処理(Textプロパティをzzzへ変更)
                              .ForEach(x => x.Text = "zzz");

        }
    }
}

参考

C#

Posted by hidepon