7

コードビハインドで動的にWPF要素を作成しています。作成している行ごとに、と動的な数でGrid構成されています。必要な相互作用は次のとおりです。CheckBoxTextBoxes

  • 行のすべてTextBoxesの値が。の場合は、プロパティを0に設定して無効にします。CheckBox IsCheckedtrue
  • のいずれかがTextBoxesから変更された場合は0、を有効にして CheckBoxをに設定IsCheckedfalseます。
  • ユーザーがをクリックした場合は、CheckBoxに関連付けられているすべてを設定TextBoxes0、を無効にしますCheckBox

私はこのコードを使用して最後の部分の最初の部分を達成することができました:

Binding setScoreToZeroIfIsNormalChecked = new Binding("IsChecked");
setScoreToZeroIfIsNormalChecked.Source = this.NormalCheckBoxControl;
setScoreToZeroIfIsNormalChecked.Converter = m_NormalCheckBoxJointScoresConverter;
tempJointScoreControl.JointScoreContainer.SetBinding(ContainerBase.SingleAnswerProperty, setScoreToZeroIfIsNormalChecked);

およびコンバーター:

public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (value is bool && targetType == typeof(Answer))
    {
        if ((bool)value)
        {
            Answer answer = new Answer();
            answer.Value = "0";
            answer.DisplayValue = "0";
            return answer;
        }
        else
            return null;
    }
    else
    {
        return null;
    }
}

ただし、他の機能を実現するために別のコンバーターを作成しようとすると、すべての機能がCheckBox.IsCheckedプロパティに基づいているため、コンバーターが相互にステップするという問題が発生していました。

1つまたは2つのマルチバインディングコンバーターを使用して上記のすべてを達成する方法はありますか?これを行うために、たくさんのイベントを作成して維持する必要はありません。

4

2 に答える 2

13

比較的簡単です。CheckBox IsChecked プロパティを中心にすべてが解決されるはずです。単純な理由から、これは双方向のプロパティです。したがって、それを変更するか、CheckBox で変更することができます。

したがって、次のように MultiBinding を使用します。

    MultiBinding multiBinding = new MultiBinding();
    multiBinding.Converter = multiBindingConverter;

    multiBinding.Bindings.Add(new Binding("Text") { Source = txtbox1});
    multiBinding.Bindings.Add(new Binding("Text") { Source = txtbox2});

    multiBinding.NotifyOnSourceUpdated = true;//this is important. 
    checkBox.SetBinding(CheckBox.IsCheckedProperty, multiBinding);

また、multiBindingConverter では、object[] 値を最初のパラメーターとして持ちます。これを IList に変換して反復処理し、true/false を返す必要がある場合は計算を実行する必要があります。(IsChecked=true または false)

ここで、CheckBox IsEnabled を CheckBox IsChecked プロパティにバインドし、BooleanInverterConverter を使用します。(CheckBox がチェックされている場合は無効にする必要があり、その逆も同様です)

最後のステップは、TextBoxes が CheckBox の実際の IsChecked プロパティをリッスンするようにすることです。TRUE の場合、それらはすべて 0 の値を表示する必要があります。それ以外の場合は、必要なものを表示できます。

そこで、新しい MultiBinding を作成します。

    MultiBinding multiBinding = new MultiBinding();
    multiBinding.Converter = textboxMultiBindingConverter;

    multiBinding.Bindings.Add(new Binding("IsChecked") { Source = checkbox1});
    multiBinding.Bindings.Add(new Binding("Text") { Source = textbox1});

    multiBinding.NotifyOnSourceUpdated = true;//this is important. 
    textbox1.SetBinding(TextBox.Text, multiBinding);

textboxMultiBindingConverter の考え方は、value[0]==FALSE の場合は Text(value[1]) を返すか、value[0]==TRUE の場合は「0」を返すことです。

于 2012-08-21T15:26:47.310 に答える
1

この問題は、MVVM を使用すると非常に簡単に解決できます。

グリッド内の行を表す ViewModel があります。テキストボックスごとに1つのプロパティと、チェックボックス用のプロパティがあります。

さらに、グリッドを含むビューのビューモデルがあり、このビューモデルは行ビューモデルのコレクションを公開します。

行の ViewModel:

public class AnswersViewModel : ViewModelBase // From MvvmLight
{
    public bool IsAnswered
    {
        get { return _isAnswered; }
        set
        {
            if(value == _isAnswered)
                return;
            _isAnswered = value;
            if(_isAnswered)
            {
                Answer1 = "0";
                Answer2 = "0";
            }

            RaisePropertyChanged("IsAnswered");
        }
    }

    public string Answer1
    {
        get { return _answer1; }
        set
        {
            if(value == _answer1)
                return;

            _answer1 = value;
            RaisePropertyChanged("Answer1");

            if(_answer1 == "0" && _answer2 == "0")
            {
                _isAnswered = true;
                RaisePropertyChanged("IsAnswered");
            }
        }
    }

    // The implementation of Answer2 is similar to Answer1
}

ビューの ViewModel:

public class FooViewModel : ViewModelBase
{
    public ObservableCollection<AnswersViewModel> Answers
    {
        get { return _answers; }
    }
}

ビューには、のプロパティにバインドする項目の Grid とItemsSource="{Binding Answers}"ControlTemplateが含まれますAnswersViewModel

スタイルのトリガーを介して処理する CheckBox を無効にします。

于 2012-08-21T14:40:55.313 に答える