wpf Null To Boolean IValueConverter 不工作

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/15357234/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 08:01:47  来源:igfitidea点击:

Null To Boolean IValueConverter not working

c#wpfnullivalueconverter

提问by mcalex

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

如何使用 IValueConverter 将空值转换为布尔值?

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.

我正在使用 wpf 尝试显示一堆布尔值(在复选框中)。创建新记录时,这些值为空,并在复选框中显示为“不确定”。我希望空值出现并保存为“假”值。

I tried to create a NullToBoolean converter that takes null values from the database and displays them as false, and thensaves 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.

我尝试创建一个 NullToBoolean 转换器,它从数据库中获取空值并将它们显示为 false,然后在用户点击保存时将它们保存为 false。(本质上,我试图避免用户必须在复选框中单击两次(一次使其为真,然后再次使其为假)。这似乎适用于导入 - 即空值显示为假 - 但除非我做了两次点击舞蹈,保存时数据库中的值不会改变。

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.

我不知道问题是因为我的代码错误,还是因为 Converter 认为没有任何变化,因此不需要ConvertBack. 我已经尝试了Mode使用 ConvertBack 在 Convert 中的所有s 和切换代码,但似乎没有任何效果。

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

有人可以指出我需要做什么来解决这个问题吗?

采纳答案by Meirion Hughes

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.

真正的问题是您没有首先初始化数据对象。不要“修复”,从头做起;建设者是好的(例如)。您还应该制作 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;
     }
}

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.

虽然这不能解决您提出的问题,但它会以一种您可以进行单元测试的方式解决您的潜在问题。即您可以测试以确保添加到您的对象列表中的值始终被初始化。

回答by DHN

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.

有关更多信息,请查看此处

回答by Eli Arbel

Simply correct your data beforeyou perform data binding. That is the only option. The converter will only work make the check box show as 'unchecked' and update your data only when you interact with the control. For example:

执行数据绑定之前,只需更正您的数据。那是唯一的选择。转换器只会使复选框显示为“未选中”并仅在您与控件交互时更新您的数据。例如:

foreach (var item in items)
{
    if (item.VarianceDescriptionProvided == null)
        item.VarianceDescriptionProvided = false;
}