DOBON.NET DOBON.NETプログラミング掲示板過去ログ

フォームとの変数のやり取り

環境/言語:[Vista、.NET Framework(3.5)]
分類:[.NET]

日頃、お世話になっております。
皆さんのお知恵を拝借頂ければと思い書き込みいたしました。

たまたま、Form同士で変数のやりとりの話を見ました。
FormをViewとしての役割のみに絞って徹底し、他Formとのやり取りは直接
参照しない方がいいという結論でした。
(今まで、私はForm同士で直接やり取りをしていました)

その際に、新しいデータソースの追加からBindingSourceクラスを簡単に
実装する方法が紹介されており、実際に検証してFormコントロールはForm
と直接やり取りしなくてもいいのがわかりました。
検証で作成し、Formコントロール(テキストボックス×2)と結びつけたの
は以下のサンプルにあるクラス(※ 1)になります。

ただ、コントロール以外の値とやり取りしたい場合に疑問が残ります。
たとえば、コントロールのWindowハンドルや一時的に格納してきたいファイ
ルのディレクトリなどです。
今まではフォームにPublicなプロパティを作成し、そこから参照させていま
した。
FormとFormを直接やり取りしないとなると、他クラスを作成しstatic宣言し
たプロパティから値を取得する方法しかわかりません。

FormにPublicなプロパティを作成するよりは、static宣言してもいいから他
クラスを中継した方がいいでしょうか?
他の方法があれば、それをご教授頂けると幸いです。

本当なら主処理の一部をFormにやらせてしまい、このような状況に陥ったの
はわかりました。
新規作成や作成半ばのアプリは、FormをViewに徹するのを念頭に入れてやっ
てみようと考えています。


※ 1
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace CommonData
{
public class CommonDataObject
{

string strTxtValue1 = string.Empty, /* TextBox1とのバインディング */
strTxtValue2 = string.Empty; /* TextBox2とのバインディング */

// 各フォームにあるTextBox1とのバインディング
public string TxtValueA
{
get
{
return this.strTxtValue1;
}
set
{
this.strTxtValue1 = value;

if (TxtValue1EventHandler != null)
{
TxtValue1EventHandler(this, new EventArgs());
}
}
}
public event EventHandler TxtValue1EventHandler;


// 他コントロールのテキスト
public string TxtValueB
{
get
{
return this.strTxtValue2;
}
set
{
this.strTxtValue2 = value;
if (TxtValue2EventHandler != null)
{
TxtValue2EventHandler(this, new EventArgs());
}
}
}
public event EventHandler TxtValue2EventHandler;

}
}
■No26042に返信(くれないさんの記事)

くれないさん、はじめまして。
私の場合は、インターフェイスを介在する方法をよく使います。

下記サンプルの Form1 と Form2 は、それぞれテキストボックスとボタンを
一つ張り付けたフォームを作成し使用します。
ISampleインターフェイスを適当なところに張り付けて使ってください。

参考になれば。

public interface ISample
{
    event EventHandler Text1Changed;
    string Text1 { get; set; }
}

public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        this.sample = new Sample();
        this.sample.Text1Changed += new EventHandler(sample_Text1Changed);
        this.form2 = new Form2(this.sample);
    }

    private Sample sample;
    private Form2 form2;

    private void sample_Text1Changed(object sender, EventArgs e)
    { this.textBox1.Text = this.sample.Text1; }

    private void button1_Click(object sender, EventArgs e)
    {
        if (this.form2.Visible == false)
        { this.form2.Show(this); }
        else
        { this.form2.Hide(); }
    }

    private void textBox1_Leave(object sender, EventArgs e)
    {
        if (this.sample.Text1 == this.textBox1.Text) return;
        this.sample.Text1 = this.textBox1.Text;
    }

    private void Form1_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (this.form2.Visible)
        { this.form2.Close(); }

        this.form2.Dispose();
        this.form2 = null;
    }

    private sealed class Sample : ISample
    {
        public Sample()
        { this.text1 = ""; }

        public event EventHandler Text1Changed;

        private string text1;

        public string Text1
        {
            get { return this.text1; }
            set
            {
                this.text1 = value == null ? "" : value;

                if (this.Text1Changed == null) return;
                this.Text1Changed(this, EventArgs.Empty);
            }
        }
    }
}

public partial class Form2 : Form
{
    public Form2(ISample sample)
    {
        if (sample == null)
        { throw new ArgumentNullException("sample"); }

        InitializeComponent();

        this.sample = sample;
        this.sample.Text1Changed += new EventHandler(sample_Text1Changed);
    }

    private ISample sample;

    private void sample_Text1Changed(object sender, EventArgs e)
    { this.textBox1.Text = this.sample.Text1; }

    private void Form2_FormClosing(object sender, FormClosingEventArgs e)
    {
        if (e.CloseReason == CloseReason.UserClosing)
        {
            e.Cancel = true;
            this.Hide();
        }
    }

    private void textBox1_Leave(object sender, EventArgs e)
    {
        if (this.sample.Text1 == this.textBox1.Text) return;
        this.sample.Text1 = this.textBox1.Text;
    }

    private void button1_Click(object sender, EventArgs e)
    { this.Hide(); }
}
Algolさん、初めましてよろしくお願いします。
ご回答ならびに、コードまで掲載して頂きましてありがとうございます。
早速提示して頂いたコードを試し、インターフェースで共有する考え方が参考になり
ました。

追加の際に変更があるのは仲介クラスとForm1のみで、
publicなプロパティも出さずに他クラスとやりとりができる点が勉強になりました。

今はIBindingListを実装した検証を行っておりますので、
想定した動きをできなかったらInterfaceでの実装でやろうと考えています。
お忙しい中、対応して頂きましてありがとうございました。
解決済み!

DOBON.NET | プログラミング道 | プログラミング掲示板