Windowsフォームラジオボタンでデータバインディングを使用するにはどうすればよいですか?

StackOverflow https://stackoverflow.com/questions/344964

質問

単一の<!> quot; Is XXXX?<!> quot; -typeチェックボックスを使用してUIで記述するのが難しいバイナリフィールドがデータベースにあります。むしろラジオボタンのペアを使用します(例:<!> quot; Do it the Foo way <!> quot;および<!> quot; Do it the Bar way <!> quot;)、しかし今はすべてフォームの他のフィールドは、ビジネスオブジェクトにデータバインドされています。ラジオボタンのペアをビジネスオブジェクトにもデータバインドしたいのですが、まだそれを行う良い方法を思いつきませんでした。フィールドに<!> quot; true <!> quot;が設定されるように、ボタンの1つをフィールドにバインドできます。ボタンが選択されているが、他のボタンを選択しても最初のボタンが選択解除されている(つまり、2つのラジオボタンが適切にペアになっている)場合、フィールドの値はこれを反映して更新されません。

発言したい

button1.DataBindings.Add(new Binding("checked", source, "useFoo"));
button2.DataBindings.Add(new Binding("checked", source, "!useFoo"));

しかし、それが実行されたときにスローされると確信しています。もっと簡単な方法はありますか、それとも単一のチェックボックスをどのように表現するかについてもっと考えるべきですか?この些細なことを処理するために、余分な関数を追加したくありません...

ETA:コメント者はドロップダウン(ComboBox)を検討することを提案しました。私はこれについて考えていましたが、それをビジネスオブジェクトのデータベース/プロパティのブールフィールドにどのようにデータバインドしますか? SelectedItemをuseFooプロパティにバインドすると、Itemsコレクションには何が入りますか? <!> quot; True <!> quot;だけを追加する必要がありますか?および<!> quot; False <!> quot ;、または表示されたアイテムを結び付けるキー/値ペアオブジェクトを何らかの方法で追加できますか(<!> quot; Use Foo <!> quot; / <!> quot; Do Not Foo <!> quot;)を使用して、その背後のブール値に?このドキュメントを見つけることができません。


答えについて:私が使用した解決策は、ビジネスオブジェクトの変更を伴うものでした-基本的な考え方はGurgeが投稿したものと非常に似ていますが、彼の回答を読む前に別に考えました。つまり、単純に!useFooを返すプロパティを追加しました。 1つのラジオボタンはsource.UseFooにバインドされ、もう1つのラジオボタンはsource.UseBar(新しいプロパティの名前)にバインドされます。新しいプロパティにゲッターとセッターの両方があることを確認することが重要です。そうしないと、本当に奇妙な動作になってしまいます。

役に立ちましたか?

解決

DataSet / DataTableを使用してこれを行う方法を見つけました。

IIF(Foo=true, false, true)という式でDataTableに計算列を作成します。その列をBarと呼びましょう。

RadioButton.Checkedはブール型です。これで、1つのFooを<=>にバインドし、もう1つを<=>にバインドできます。

<=>チェック/チェック解除を取得して<=>に戻すには、生成されたDataTableコードに移動して、このサンプルの最後の1行を追加する必要があります。

[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public bool Bar {
    get {
        try {
            return ((bool)(this[this.tableradio.BarColumn]));
        }
        catch (global::System.InvalidCastException e) {
            throw new global::System.Data.StrongTypingException("The value for column \'Bar\' in table \'radio\' is DBNull.", e);
        }
    }
    set {
        this[this.tableradio.BarColumn] = value;
        this[this.tableradio.FooColumn] = !value;
    }
}

他のヒント

  1. ブール値に直接リンクされているRadioButtonをバインドします(値がtrueのときにチェックされます)。
  2. このCheckedChangedの次のような<=>イベントにイベントハンドラーを追加します。

    private void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        foreach (Binding b in ((Control)sender).DataBindings)
            b.WriteValue();
    }
    

ビジネスオブジェクトがINotifyPropertyChangedを実装している場合(バインディングの動作が改善されます)、次のコードをビジュアルインターフェイスに追加できます。BOはビジネスオブジェクトであり、eventsで宣言され、BO.Valueは希望するブール値プロパティバインドする。

Public Property NotValue() As Boolean
    Get
        Return Not BO.Value
    End Get
    Set(ByVal value As Boolean)
        BO.Value = Not value
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue"))
    End Set
End Property


Private Sub BO_PropertyChanged(ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Handles BO.PropertyChanged
    If e.PropertyName = "Value" Then
        RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs("NotValue"))
    End If
End Sub

次のバインディングはラジオボタンを接続します。

RBTrue.DataBindings.Add(New Binding("Checked", Me.BO, "Value", False, DataSourceUpdateMode.OnPropertyChanged))
RBFalse.DataBindings.Add(New Binding("Checked", Me, "NotValue", False, DataSourceUpdateMode.OnPropertyChanged))

ビジュアルインターフェイスもINotifyPropertyChangedを実装する必要があります。このメソッドは双方向に機能します。インターフェイスが変更されると元の値が更新され、元の値が変更されるとインターフェイスは正しく更新されます。

同じ問題に遭遇し、標準のデータバインディングで実際に可能であることがわかりました:

button1.DataBindings.Add(new Binding("checked", source, "useFoo", false, DataSourceUpdateMode.OnPropertyChanged);
// no need to databind button 2, since button1.checked 
// is set to false when button2 is checked

デフォルトでは、DataSourceUpdateModeOnValidationに設定されます。これをOnPropertyChangedに設定すると、変更はすぐにデータバインドされたオブジェクトに伝播されます。

私のビジネスオブジェクトはINotifyPropertyChanged;

を実装します

このソリューションをテストすると、button2をクリックしたときに<=>イベントが2回発生することがわかりました。これを防ぐには、単に設定します

button1.CausesValidation = false;
button2.CausesValidation = false;

ここに示すように: TextBoxの離脱によりPropertyChangedが2回発生する

コードで手動で実行します。フォームをロードするとき、データベースに従ってラジオボタンを設定します。 <!> quot; save <!> quot;を押すと、あなたが望む状態でボタンストア。この例では、無線をデータベースのビットフィールドとして保存します。

        // Load radio state
        radioButton1.Checked = ((myModel)myBindingSource.DataSource).boolOption1;
        radioButton2.Checked = ((myModel)myBindingSource.DataSource).boolOption2;

-

        // Save radio state
        ((myModel)myBindingSource.DataSource).boolOption1 = radioButton1.Checked;
        ((myModel)myBindingSource.DataSource).boolOption2 = radioButton2.Checked;

<!> quot; Data Sources <!> quot;からアイテムをドラッグしようとしました。 Visual Studio 2015のパネルで、ラジオボタンをテーブルでブール値として定義したが、別のラジオボタンが選択されたときにブール値がfalseに更新されないという問題がある。 <!> quot; causesValidation <!> quot;を変更する場合他のテキスト入力フィールド間をジャンプするときに自動的にオフにされるfalseラジオボタンに。

コントロールが同じグループにあることを確認する限り、コントロールの1つのみをバインドする必要があります。

ドロップダウンも検討できます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top