8

IValueConverter を使用して null をブール値に変換するにはどうすればよいですか?

wpf を使用して、多数のブール値を (チェックボックスで) 表示しようとしています。新しいレコードが作成されると、これらの値は null になり、チェックボックスに「不確定」として表示されます。null が表示され、「false」値として保存されるようにします。

データベースから null 値を取得して false として表示し、ユーザーが保存を押したときに false として保存する NullToBoolean コンバーターを作成しようとしました。(基本的に、ユーザーがチェックボックスを2回クリックする必要がないようにしています(1回はtrueにし、次にもう一度falseにする)。これはインポートで機能するようです-つまり、null値はfalseとして表示されます-ただし、 2 クリック ダンスを実行すると、保存時にデータベースの値が変更されません。

私のコンバーター:

[ValueConversion(typeof(bool), typeof(bool))]
public class NullBooleanConverter : IValueConverter
{

  public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  {
    if (value != null)
    {
      return value;
    }
    return false;
  }

  public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  {
    if (value != null)
    {
      return value;
    }
    return null;
  }
}

コンバーターを動作させようとしているチェックボックスの1つ:

    <CheckBox Grid.Column="1" Grid.Row="0" Padding="5" Margin="5" VerticalAlignment="Center" Name="chkVarianceDescriptionProvided" IsThreeState="False">
      <CheckBox.IsChecked>
        <Binding Path="VarianceDescriptionProvided" Mode="TwoWay">
          <Binding.Converter>
            <utils:NullBooleanConverter />
          </Binding.Converter>
        </Binding>
      </CheckBox.IsChecked>
    </CheckBox>

私のコードが間違っているために問題が発生したのか、それともコンバーターが何も変更されていないと考えているため、変更する必要がないのかはわかりませんConvertBackModeConvertBack を使用して Convert ですべてのs とスイッチ コードを試しましたが、何も機能しないようです。

誰かがこれを修正するために何をする必要があるかを指摘できますか?

4

3 に答える 3

22

うーん、箱から出してすぐに使用できるのに、なぜコンバーターを使用するのですか?

<CheckBox IsChecked="{Binding VarianceDescriptionProvided, TargetNullValue=False}" />

詳細については、こちらをご覧ください。

于 2013-03-12T10:47:07.477 に答える
1

本当の問題は、そもそもデータ オブジェクトを初期化していないという事実です。「修正」しないでください。最初から正しく実行してください。ビルダーは良いです(たとえば)。また、モデル (データベースなど) を直接操作するのではなく、ViewModels/DataModels を作成する必要があります。

public class MyObjectBuilder
{
     Checked _checked;

     public  MyObjectBuilder()
     {
          Reset()
     }

     private void Reset()
     { 
          _checked = new Checked(true); //etc
     }

     public MyObjectBuilder WithChecked(bool checked)
     {
          _checked = new Checked(checked);
     }

     public MyObject Build()
     {
         var built = new MyObject(){Checked = _checked;} 
         Reset();
         return built;
     }
}

次に、常にビルダーで初期化します

myObjects.Add(new MyObjectBuilder().Build());

また

myObjects.Add(_injectedBuilder.Build()); // Initialises Checked to default 
myObjects.Add(_injectedBuilder.WithChecked(true).Build()); //True

これは質問された問題を解決しませんが、ユニットテストができる方法で根本的な問題を解決します。つまり、オブジェクト リストに追加された値が常に初期化されることをテストできます。

于 2013-03-12T09:58:38.353 に答える
0

データ バインディングを実行する前に、データを修正するだけです。それが唯一の選択肢です。コンバーターは、チェック ボックスを「未チェック」として表示し、コントロールを操作した場合にのみデータを更新する場合にのみ機能します。例えば:

foreach (var item in items)
{
    if (item.VarianceDescriptionProvided == null)
        item.VarianceDescriptionProvided = false;
}
于 2013-03-12T09:56:08.517 に答える