2012年10月11日木曜日

VB ひとつのフォームを編集・閲覧で切り替える

先ほど、msdn の VB Forum でフォームを閲覧用にするご質問がありました。
データベースを操作する上で、閲覧と編集とを分けて考える事は重要ですが、逆に双方を同じ様な画面で扱いたいのも事実でしょう。
使う上で、画面イメージが統一されている事は、慣れ易さからも重要です。
ここでは、ひとつの変数に対し、閲覧・編集を切り替えて使う別のひとつのフォームを表示する例を示します。


データベース (以下 DB と略) を操作する上で、同じ画面で、閲覧と編集とを行き来する手段を用意しておくと便利な場合があります。
実現方法は色々あるとは思いますが、一例と思ってご覧下さい。

実装時には、DB から Fill したり EndEdit や UpdateAll したりといった取得・保存の操作が必要ですが、今回は省きます。
また、 DataTable で扱う事が多いと思いますが、今回は、単なる変数で例示します。


VB のデザイナーで用意する Form は以下の2つです。
ひとつの変数に対して、閲覧時は TextBox 編集時はComboBox で表示させます。
実装時はこのふたつを重ね合わせて配置しますが、動作が分り易いように、例示では別の位置にしました。
編集で別の項目を指定すると、変数にその値が代入されます。


実行時の画面です。
標準状態で貼り付けただけですが、
例示する Code では Form2 のControl の幾つかで .Name Property を変更しています。

各 Form に対する Code は
Public Class Form1
    Friend IsFormEdit As Boolean = True
    Friend testValue As String = "Test Value"
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.Label1.Text = "閲覧モードの実行"
        Me.Label2.Text = "モード:??"
        Me.Label3.Text = "各モードの実行"
        Me.Button1.Text = "閲覧"
        Me.Button2.Text = "モード変更"
        Me.Button3.Text = "実行"
    End Sub
    Private Sub ModeChangeForm2(ByVal IsEditMode As Boolean)
        If IsEditMode Then
            Form2.ComboBox1.Enabled = True      '実際は .visible で
            Form2.TextBox1.Enabled = False         '実際は .visible で
            Form2.Label21.Text = "編集"
        Else
            Form2.ComboBox1.Enabled = False     '実際は .visible で
            Form2.TextBox1.Enabled = True          '実際は .visible で
            Form2.Label21.Text = "閲覧"
        End If
        ' その他、コントロールの詳細指定はすべて IF 文の中にまとめる
    End Sub
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        IsFormEdit = False
        ModeChangeForm2(IsFormEdit)
        Form2.Show()
    End Sub
    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
        IsFormEdit = Not IsFormEdit
        Me.Label2.Text = "モード:" + IIf(IsFormEdit, "編集", "閲覧")
    End Sub
    Private Sub Button3_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button3.Click
        Me.Label2.Text = "モード:" + IIf(IsFormEdit, "編集", "閲覧")
        ModeChangeForm2(IsFormEdit)
        Form2.Show()
    End Sub
End Class
Public Class Form2
    Private Sub Form2_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        Me.TextBox1.Text = Form1.testValue
        Me.ComboBox1.Text = Form1.testValue
        Me.ComboBox1.Items.Add("TEST Combo 0")
        Me.ComboBox1.Items.Add("TEST Combo 1")
        Me.ComboBox1.Items.Add("TEST Combo 2")
        Me.Button21.Text = "OK"
        Me.Button22.Text = "Cancel"
        'TextBoxは表示用 Label にしても良い
        Me.TextBox1.ReadOnly = True
    End Sub
    Private Sub Button21_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button21.Click
        If Form1.IsFormEdit Then
            Form1.testValue = Me.ComboBox1.Text
        End If
        Me.Close()
    End Sub
    Private Sub Button22_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button22.Click
        Me.Close()
    End Sub
End Class 
ポイントは、

Form1 は閲覧・編集の指定のみ、実際の表示は Form2 で行います。

表示対象となる変数 testValue を Friend 指定し、Form2 から格納値を変更できるようにした事。
Form2 の編集・閲覧 状態を示す変数 IsFormEdit も、同様に、 Friend 指定し、 Form1 で指示し Form2 で条件判断に使った事。

変数 IsFormEdit に応じて Form2 で表示する各 Control の詳細指定をする Sub ModeChangeForm2 。
各 Button からのイベントハンドラで、実際に Sub ModeChangeForm2 を引数付きで呼び出します。
その後、実際に Form2 を Show で表示させます。

編集時、 Form2 で OK Button を押された時のみ、Form1 で宣言した testValue の値を変更する様にします。 Cancel 時には、値は変更されません。

例外処理や細かい操作は省いているので、実装時に考えて下さい。


表示させる対象によって、編集のみにする場合は Form1 の Button2 & 3 で .Enable = False にする事で対処できます。
汎用的に利用するには .Visible ではなく .Enable を用い、機能が使えない事を明示すると良いでしょう。
同じ様に、 Form2 に閲覧・編集の文字表示をしましたが、これも必須でしょう。 色を赤などに変えても良いと思います。


今回の例の様に単純な場合はあまりメリットがありませんが、DB で表示する項目が増えて来ると、その後のメンテで楽になると思います。
 Sub ModeChangeForm2 を弄れば済む訳ですから。


各指定に Button を用いた例を示しましたが、UI はこれに限りません。

私は、住所録のプログラムを VB の練習のつもりで昔に作りましたが、Tab Control を使い、一覧 DataGridView と 個別 TextBox & ComboBox とで閲覧・編集を共通画面化・機能分離しました。
その前は、閲覧のつもりで DataGridView を見ていて、間違ってデータを変えてしまっている事があったので ... 。
今回ご紹介したものと実装方法は違いますが、考え方は一緒です。
使った感想は、今自分がしている作業が閲覧なのか編集なのかを表示しておく事の重要さでしょうか。
同じ様な画面構成で、閲覧も編集も出来るのは、使い易いですよ。
ただ、トラブルの元も多いので、運用前の充分なテストが不可欠です。

0 件のコメント:

コメントを投稿