Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Null To Boolean IValueConverter not working

How do I use an IValueConverter to convert nulls into booleans?

I'm using wpf to try to display a bunch of boolean values (in checkboxes). When a new record is created, these values are null, and appear as 'indeterminate' in the checkboxes. I want the nulls to appear and save as 'false' values.

I tried to create a NullToBoolean converter that takes null values from the database and displays them as false, and then saves them as false when the user hits save. (Essentially, I'm trying to avoid the user having to click twice in the checkboxes (once to make it true, then again to make it false). This seems to work on import - ie null values are shown as false - but unless I do the two-click dance the value doesn't change in the database when I save.

My Converter:

[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;
  }
}

One of the checkboxes I'm trying to have the Converter work with:

    <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>

I don't know if the problem is because my code is wrong, or if it's a case of the Converter thinking that nothing has changed, therefore it doesn't need to ConvertBack. I have tried all the Modes and switched code in Convert with ConvertBack, but nothing seems to work.

Can someone point out what I need to do to fix this?

like image 458
mcalex Avatar asked Mar 12 '13 09:03

mcalex


2 Answers

Hmm, why using a converter, if you can have it out of the box?

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

For more information, pls have a look here.

like image 94
DHN Avatar answered Oct 19 '22 19:10

DHN


The real problem is the fact you are not initializing your data objects in the first place. Don't "fix", do it right to begin with; builders are good (for example). You also should be making ViewModels/DataModels rather than working with your Models (database, etc) directly.

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;
     }
}

then always initialise with the builder

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

or

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

While this doesn't fix your asked problem, it will fix your underlying problem in a way you can Unit Test. i.e. you can test to ensure the values added into your object list are always initialized.

like image 1
Meirion Hughes Avatar answered Oct 19 '22 18:10

Meirion Hughes