9

データベースに、「Is XXXX?」タイプのチェックボックスを 1 つ使用して UI で説明するのが難しいバイナリ フィールドがあります。ラジオ ボタンのペアを使用したいのですが (例: "Do it the Foo way" と "Do it the Bar way")、現在、フォームの他のすべてのフィールドはビジネス オブジェクトにデータ バインドされています。ラジオ ボタンのペアをビジネス オブジェクトにもデータ バインドしたいのですが、まだ良い方法が思い浮かびません。ボタンの 1 つをフィ​​ールドにバインドして、ボタンが選択されている場合はフィールドが「true」に設定されますが、他のボタンを選択すると最初のボタンが選択解除されます (つまり、2 つのラジオ ボタンが適切にペアになっています)。 )、フィールドの値はこれを反映して更新されません。

言えるようになりたい

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

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

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


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

4

6 に答える 6

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

    private void radioButton_CheckedChanged(object sender, EventArgs e)
    {
        foreach (Binding b in ((Control)sender).DataBindings)
            b.WriteValue();
    }
    
于 2009-09-16T10:02:20.693 に答える
1

ビジネス オブジェクトが INotifyPropertyChanged を実装している場合 (これにより、バインディングがより適切に機能します)、次のコードをビジュアル インターフェイスに追加できます。ここで、BOはビジネス オブジェクトであり、withevents で宣言され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 も実装する必要があります。この方法は双方向に機能します。インターフェイスが変更された場合は元の値が更新され、元の値が変更された場合はインターフェイスが正しく更新されます。

于 2008-12-18T17:56:09.780 に答える
1

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

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

Barブール型です。これで、1 つを に、もう 1つRadioButton.Checkedを にバインドできます。FooBar

チェック/チェック解除をBar反映して戻すにFooは、生成された 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;
    }
}
于 2008-12-06T00:06:54.870 に答える
-3

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

DropDown を検討することもできます。

于 2008-12-05T22:14:02.073 に答える