トップ回答者
フォームの終了時の処理

質問
-
質問です。
よろしくお願いします。
5つのテキストボックスに値が入っている状態で始まり、そのテキストボックス内の値が変わっていたら、フォームを閉じる(×ボタンを押す)際にダイアログを出すことをやってみたいのですが、
hikakuの部分で値を返さないコードがありますとエラーが表示されます。
①フォームをロードした際にテキストボックス内の値をArrayListにいれる。
②フォームを閉じる際に再度テキストボックス内の値をArrayListにいれる。
③比較を1つ1つ比較して異なるものがあえば Falseを返す。変わっていないのであれば Trueを返す。
④返ってきた値が Falseならばダイアログを出す。Trueならば出さすに終了。
としたいのですが、2つのArrayListをメソッドに渡して、その判定をしたいのですが、うまくいきません。
解決方法はありますでしょうか?
○また、ユーザーコントロールなどで画面がたくさんある場合に
この処理を使いまわせるようなよい方法はないでしょうか?
もっと簡潔にしたいとも考えています。
基本的な勉強の最中ですので、言い回しなどが間違っている部分がありますが、よろしくお願いします。
using System;
using System.Collections;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
private ArrayList data = new ArrayList();
private ArrayList data2 = new ArrayList();
public Form1()
{
InitializeComponent();
}
//フォームロード時に値を読み込み。
public void Form1_Load(object sender, EventArgs e)
{
data.Add(textBox1.Text);
data.Add(textBox2.Text);
data.Add(textBox3.Text);
data.Add(textBox4.Text);
data.Add(textBox5.Text);
}
//閉じるときのイベント
private void Form1_FormClosing(object sender, FormClosingEventArgs e)
{
data2.Add(textBox1.Text);
data2.Add(textBox2.Text);
data2.Add(textBox3.Text);
data2.Add(textBox4.Text);
data2.Add(textBox5.Text);
Boolean tf = hikaku(data, data2);
if (tf)
{
if (DialogResult.No == MessageBox.Show(
"終了しますか?", "終了確認", MessageBoxButtons.YesNo))
{
e.Cancel = true;
}
}
}//最初と閉じる直前の値を比較(ここでエラー)
public static Boolean hikaku(ArrayList data, ArrayList data2)
{
for (int i = 0; i < data.Count; i++)
{
string a = Convert.ToString(data[i]);
string b = Convert.ToString(data[i]);
if ( a != b)
{
return false;
}
}
}
}
}
回答
-
「値を返さないパスがあります」とは、ループや分岐をすべて見ていった結果、return がない場所があるということです。
実際、hikaku 関数を見ると return true; が存在していません。- 回答の候補に設定 Ashidacchi 2019年2月9日 8:42
- 回答の候補の設定解除 so-sara-yamashita 2019年2月12日 1:33
- 回答としてマーク so-sara-yamashita 2019年2月12日 1:34
すべての返信
-
「値を返さないパスがあります」とは、ループや分岐をすべて見ていった結果、return がない場所があるということです。
実際、hikaku 関数を見ると return true; が存在していません。- 回答の候補に設定 Ashidacchi 2019年2月9日 8:42
- 回答の候補の設定解除 so-sara-yamashita 2019年2月12日 1:33
- 回答としてマーク so-sara-yamashita 2019年2月12日 1:34
-
○また、ユーザーコントロールなどで画面がたくさんある場合に
この処理を使いまわせるようなよい方法はないでしょうか?
もっと簡潔にしたいとも考えています。
用意されているArrayListを変更検証用としてだけ使われていますが、これに変えてUIオブジェクトにする方法があります。
基本的にはデータを直接フォームに表示せず、UIオブジェクトにデータをセットし、UIオブジェクトとバインド等すると良いです。たまにDataTableを直接バインドされてDataTable使いにくいダメだと言われている方を見かけますが、これは当たり前のことで、バインド用の設計になっていないからです。このUIオブジェクトを利用して変更の検出も行えます。UIオブジェクトには変更後の値が反映されています。最初にUIオブジェクトにセットした値があるはずですから、それと比較すれば良いです。
(例)
DataTableにデータを読み、UIオブジェクトにその値をセットし、UIオブジェクトをフォームにバインドする。
UIオブジェクトの値とDataTableを比較すれば変更されたかどうかがわかる。私は全ての入力画面にこの仕組みを入れています。
UIオブジェクトの簡単な例を以前アップしていますので参考になると思います。WindowsフォームにおけるIDataErrorInfoの実装サンプル
https://code.msdn.microsoft.com/WindowsIDataErrorInfo-637ebea1なお、以下が大変参考になると思います。
Part 2. スマートクライアントにおける単体入力データ検証
https://blogs.msdn.microsoft.com/nakama/2009/02/26/part-2-2/さて、話を戻して汎用的な比較の仕組みが用意できないか?ということですが、単純な場合を除いて、経験上これは無理だと思います。
データの種類によっては単純に比較できないこともあります。例えばユーザーが入力する以外のところで自動的に値をセットするような場合もあります。また、UIオブジェクト上の型とDataTable上の型が違うような場合も考えられます。
(ヒント)
UIオブジェクトを作成するのも、上記のような比較メソッドを作成するのもコーディング量が多くて手間です。ですから、私はT4で自動生成してしまいます。
★良い回答には質問者は回答済みマークを、閲覧者は投票を!
- 編集済み trapemiyaModerator 2019年2月8日 1:40 紹介ページの誤り修正