2016-10-27 27 views
1

データがあらかじめロードされているフォームが約20個あります(ComboBoxTextBoxなど)。これはユーザーに表示され、フィールドのいずれかを変更する機能をユーザーに提供します。選択/テキストが書式で変更されているかどうかを確認してください。

変更が行われたことを認識する最良の方法はわかりません。いくつかの調査の後、私はTextBox.TextChangedを見つけて、その行に沿ってフラグIsDirty = Trueか何かを設定しました。

ユーザーは値を変更してから最初に読み込んだときの状態に戻す可能性があるため、これは100%防弾にはならないと思います。私は現在のデータを.Tagに保存し、ユーザーが「キャンセル」をクリックして変更を保存するかどうかを尋ねるときに入力した.Textと比較することを考えていました。

これは私のコードです:

Private Sub Form1_Load(ByVal sender as Object, byVal e as System.EventArgs)Handles MyBase.Load 
    For Each ctr as Control in me.Controls 
     if typeof ctr is TextBox then 
     ctr.tag=ctr.text 
     end if 
    Next 
End Sub 

これは、ユーザーが「キャンセル」をクリックするときのためのコードです:

Private Sub CmdCancel_Click (ByVal sender as Object, ByVal e As System.EventArgs) Handles CmdCancel.Click 
    For each ctr As Control in Me.Controls 
     If Typeof ctr is Textbox then 
      if ctr.tag.tostring <> ctr.text then 
       MsgBox ("Do you want to save the items", YesNo) 
      end if 
     End if 
    Next 
End sub 

が、これは、これを行うために効果的な方法ですか?それは信頼できるのだろうか?誰かがもっと良いアイデアを持っているなら、私はそれを聞いてみたい。

+1

組み込みの方法がいくつかあります。一つは 'Modified'プロパティです。また、 'Tag'を使うのではなく、(データテーブルのような)ソースと比較することもできます。もう1つは、バインドされたコントロールを使用する場合、データテーブルは変更された行をマークすることです。私はそれがどちらかの変更変更のバック状況をキャッチするとは思わない。 – Plutonix

+1

テキストボックスを継承するプロジェクトにカスタムコントロールを追加し、そのテキストがプログラマチックに設定されるたびにTextBoxの内容をOriginalTextプロパティに保存するために.Textメソッドをオーバーロードすることができます。次に、テキストボックスの現在のテキストと元のテキストを比較するreadonlyプロパティを1つ追加し、テキストが変更されている場合はTrueを返します。 – soohoonigan

答えて

2

はこれを見ている:

For Each txtBox In Me.Controls.OfType(Of TextBox)() 
    If txtBox.Modified Then 
     'Show message 
    End If 
Next 

EDIT

は、このを見てください。あなたは.Tagプロパティに別の方法を望んでいた場合、これはあなたに興味がある可能性があります

'Declare a dictionary to store your original values 
Private _textboxDictionary As New Dictionary(Of TextBox, String) 

Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load 

    'You would place this bit of code after you had set the values of the textboxes 
    For Each txtBox In Me.Controls.OfType(Of TextBox)() 
     _textboxDictionary.Add(txtBox, txtBox.Text) 
    Next 

End Sub 

その後、元の値を見つけると、新しい値と比較するためにこれを使用します。

For Each txtBox In Me.Controls.OfType(Of TextBox)() 
    If txtBox.Modified Then 
     Dim oldValue = (From kp As KeyValuePair(Of TextBox, String) In _textboxDictionary 
         Where kp.Key Is txtBox 
         Select kp.Value).First() 
     If oldValue.ToString() <> txtBox.Text Then 
      'Show message 
     End If 

    End If 
Next 
+1

元のテキストと比較する必要がありますか? – BobSki

+1

あなたが何をしているかによって変わります。彼らが何であるかにかかわらず何らかの変更が加えられた場合、私はこれを使用します。ある意味では、フォームが汚いと言っているようです。あなたが本当に新しい値に対して古い値をチェックする必要があるなら、あなたがしたことは問題ありません。コントロールが 'TextBox'であるかどうかをチェックするのではなく、' For Each'を私が行ったことに変更したいだけかもしれません。代わりの方法は独自の 'TextBox'クラスを作成することですが、それはもう少し複雑になり、おそらく必要ないでしょう。 – Bugs

+1

これは、フォーム上のテキストボックスを直ちに反復処理する適切な方法です(フォーム内のコンテナではありません)。しかし、それはかなり質問に答えていません – djv

2

は、私が知っていますこれはすでに受け入れられている答えがありますが、実際のテキスト値が変更されたかどうかをチェックする部分については対処する必要があると思いました。変更を確認すると、テキストに変更が加えられたかどうかが明らかになりますが、ユーザーが文字を追加して削除すると失敗します。私はこれを行う良い方法は、カスタムコントロールを使用することだと思うので、ここでは、テキストボックスの元のテキストをプログラムによって変更するたびに保存する単純なコントロールの例を示します。ユーザーの変更により、実際にテキストが元の状態と異なっていました。この方法では、テキストボックスにデータを入力するたびに、設定した値が保存されます。それで準備が整ったら、TextAlteredプロパティをチェックするだけです:

Public Class myTextBox 
    Inherits System.Windows.Forms.TextBox 
    Private Property OriginalText As String 
    Public ReadOnly Property TextAltered As Boolean 
     Get 
      If OriginalText.Equals(MyBase.Text) Then 
       Return False 
      Else 
       Return True 
      End If 
     End Get 
    End Property 
    Public Overrides Property Text As String 
     Get 
      Return MyBase.Text 
     End Get 
     Set(value As String) 
      Me.OriginalText = value 
      MyBase.Text = value 
     End Set 
    End Property 
End Class 
+0

私はクラスルートを降りることを考えていました。私は誰かがそれを技術的には答えとして示してくれてうれしいです。標準コントロールがまだそれをサポートしていないのは残念ですが、私は多くの人がそれを感謝するだろうと確信しています。 – Bugs

関連する問題