2017-12-15 8 views
0

Visual Basic .NETを使用してWindowsフォームアプリケーションを開発しています.TextBoxに何かがある場合に、ボタンの有効なプロパティを切り替える必要があります。私は、次を使用してセットアップにデータバインディングを実行しようとしました:DataBinding - トグルを有効にする入力に基づいて

ButtonBack.DataBindings.Add("Enabled", Me.TextBoxValue, "TextLength") 

これが正常にボタンを無効にしますが、何をテキストボックスに入力されたときに、ボタンが有効れることは決してありません。 TextBoxのTextChangedまたはValidatingイベントでEnabledプロパティを手動で設定するのではなく、可能であればDataBindingsを使用してこれを行うことをお勧めします。

+0

WinFormsには、データバインディングに関して多くの制限があります。 TextLengthは、何かが変更されたという通知を提供しない読み取り専用のプロパティです。 'AddHandler TextBoxValue.TextChanged、Sub()ButtonBack.DataBindings(0).ReadValue()End Sub'を追加することで不正行為をすることができます。これは、DataBindingを使用しないほうが良いということは、痛ましいことです。 – LarsTech

答えて

1

@LarsTechがコメントで述べたように、変更された通知を発生させるTextBoxクラスのプロパティを使用する必要があります。 Textプロパティは適切なプロパティです。

これを厳密にバインディングで行うことは可能ですが、依然としてイベントハンドラを使用する必要があります。このように、私はTextBoxValue.TextChangedイベントを処理する以上のこのアプローチでは多くの価値を見ません。

これを行う1つの方法は、Binding.Format Eventを使用して、文字プロパティが含まれている場合に基づいて、テキストプロパティの文字列をブール値に変換することです。

Dim b As Binding = ButtonBack.DataBindings.Add("Enabled", Me.TextBoxValue, "Text", True, DataSourceUpdateMode.OnPropertyChanged) 
AddHandler b.Format, Sub(s As Object, args As ConvertEventArgs) args.Value = Not String.IsNullOrEmpty(CStr(args.Value)) 

結合するので、あなたのコードがButtonBack.Enabledプロパティを変更した場合、それが戻っTextBoxValueにプロパティの文字列表現を送信し、そのテキストは「True」または「False」読みます、2つの方法です。これは望ましい結果ではありません。この可能性を修正するには、Binding.Parse Eventを処理する必要があります。

AddHandler b.Parse, Sub(s As Object, args As ConvertEventArgs) args.Value = Me.TextBoxValue.Text 
+0

このソリューションは「最も速い」実装を提供するように見えるかもしれませんが、長期的には、特にこのように多くのコントロールを有効/無効にする必要がある場合は、保守が難しくなります。 Bindingオブジェクトの解析と書式設定イベントは、それだけではなく、副作用を導入するのではなく、値の解析と書式設定に使用する必要があります。 –

1

私は通常、あなたの場合のように、「新しい」プロパティを必要とするコントロール「サブクラス」によって結合カスタムプロパティのこの種を実装するには、TextBoxHasLengthブール型プロパティを必要とする(またはあなたがそれを与えるために好きな名前)。ここで

MyTextBox.vbです:

Public Class MyTextBox 
    Inherits TextBox 

    Public Event HasLengthChanged As EventHandler 

    Private _HasLength As Boolean 
    Public Property HasLength() As Boolean 
     Get 
      Return _HasLength 
     End Get 
     Set(ByVal value As Boolean) 
      If value <> _HasLength Then 
       _HasLength = value 
       OnHasLengthChanged() 
      End If 
     End Set 
    End Property 

    Public Sub New() 
     _HasLength = False 
    End Sub 

    Protected Sub OnHasLengthChanged() 
     RaiseEvent HasLengthChanged(Me, New EventArgs()) 
    End Sub 

    Protected Overrides Sub OnTextChanged(e As EventArgs) 
     MyBase.OnTextChanged(e) 
     HasLength = Not (String.IsNullOrEmpty(Text)) 
    End Sub 
End Class 

そして、ここではForm1.vbです:

もちろん
Public Class Form1 

    Protected Overrides Sub OnLoad(e As EventArgs) 
     MyBase.OnLoad(e) 

     ButtonBack.DataBindings.Add("Enabled", Me.MyTextBox1, "HasLength", True, DataSourceUpdateMode.OnPropertyChanged) 

    End Sub 

End Class 

、あなたはMyTextBoxインスタンスと通常のButtonインスタンスでフォームを必要としています。

この方法では、ユーザーがテキストボックスに何かを入力するとすぐにボタンが有効になり、テキストボックスが空になるとボタンが無効になります。 DataSourceUpdateMode.OnPropertyChangedを使用して、テキストボックスのフォーカスが失われたときだけでなく、入力時に更新が行われるようにしました。

EDIT:.NETのPropertyNameChangedパターンに関する背景を少し追加したいと思っていました。

オブジェクトでプロパティが変更され、ほとんどの場合、INotifyPropertyChangedインターフェイスを使用しますが、コントロールに対しては、PropertyNameChangedのパターンを使用することをお勧めしますしたがって、Bindingオブジェクトはそのジョブを実行し、目的のプロパティがいつ変更されたかを知ることができます。

INotifyPropertyChangedは、バインディングに参加するデータオブジェクトにお勧めします。

ところで、PropertyNameChangedはWindowsフォームとWPFの両方で動作します。

https://docs.microsoft.com/en-us/dotnet/framework/winforms/how-to-apply-the-propertynamechanged-pattern

EDIT 2:私はC#のプログラマーだ、と私はVB.NETの私が持っている残留知識を適用するために最善をやった参照MSDNとして

。すべてのエラーは、私がVBで錆びすぎているという結果です。ご迷惑をおかけして申し訳ありませんが、コードはここでうまく動作します。

関連する問題