【问题标题】:Null To Boolean IValueConverter not workingNull 到 Boolean IValueConverter 不起作用
【发布时间】:2013-03-12 09:14:17
【问题描述】:

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

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

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

我的转换器:

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

我试图让转换器使用的复选框之一:

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

我不知道问题是因为我的代码错误,还是转换器认为没有任何改变,因此不需要ConvertBack。我已经尝试了所有Modes 并在使用 ConvertBack 进行转换时切换了代码,但似乎没有任何效果。

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

【问题讨论】:

  • 长得丑的男人。您是否将 Null 转换为 false 并将 not-null 转换为 true?因为你没有那样做。在转换回来时,您将 bool(永远不会为空)转换回 bool。
  • 您是否检查过您的转换器代码是否正常?
  • 顺便说一句,“当创建新记录时,这些值为空......”是问题;解决这个问题。您应该制作“视图友好”的 ViewModels / DataModels。
  • @MeirionHughes 我认为您的评论会比我在回答中提出的更好的方法来解决这个问题。我认为您可以自己将其作为答案。
  • @MeirionHughes。不。Null 为 false,其他所有内容(始终为布尔值)为给定值。任何美化建议都很乐意接受:-)。评论 2)它们在数据库中可以为空(我无法更改)并且 EF 负责所有的创建。我想我可以使用 ValueConverter 创建一个视图友好的 ViewModel。对 Sandeep Singh Rawat:是的,我已经取出了我的 MessageBox/调试代码,但肯定是在使用方法。

标签: c# wpf null ivalueconverter


【解决方案1】:

嗯,如果可以开箱即用,为什么要使用转换器?

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

欲了解更多信息,请查看here

【讨论】:

  • 我不知道 TargetNullValue,非常感谢。但是,这不会将“False”值保存回数据库(即,保存后它们仍然为 NULL)。它与转换器当前所做的工作相同,因此我将在解决更大的问题时使用它。
  • 好的,只是尝试一下。我不确定该值是否传递给 VM。感谢您让我了解情况。 :)
  • 很有趣,因为 doco: (msdn.microsoft.com/en-us/library/…) 说它是一个 getter 和 setter - 但没有给出设置示例。
  • 是的,TargetNullValue 属性本身有一个 getter 和 setter。这就是为什么你可以传递一个值给它。但它仍然不能确保该值通过绑定传递到 VM。想一想,就有了更深的意义。使用TargetNullValue,您可以让视图有机会解释NULL,而不会干扰可能在复杂逻辑中处理的底层虚拟机或数据。它坚持解耦的原则。 :)
【解决方案2】:

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

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

【讨论】:

  • 感谢@Meirion-Hughes。我明白你的意思,并且可以按照你的想法到达我想去的地方。对象构造中的默认值 - 就可以了。当我开始做这件事时,我不知道 mvvm,所以它目前是 wpf 完成的 old-skool(事件处理程序,一些意大利面条,代码隐藏中的数据验证等),在我学习如何适应它们时添加了 mvvm 功能. 旨在使我的下一个项目完全 mvvm,但必须通过当前的混合工作,我已经着手这个。再次感谢
  • 谷歌,Caliburn Micro。太棒了。
  • 我研究了一些框架。不幸的是,他们都没有详细说明如何将意大利面条变成 mvvm。 Caliburn 看起来确实令人印象深刻,并且可能是我开始新项目的基础。干杯
【解决方案3】:

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

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

【讨论】:

  • 随机添加物品会失败;您需要添加一个可观察列表,收听它并修复添加到其中的任何新项目。你也可以在制作它们时确保它们是正确的。
  • 每次从 EF 获得结果时只需运行此代码。不需要复杂的包装器等
猜你喜欢
  • 1970-01-01
  • 2015-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-17
  • 2016-03-18
  • 2018-08-19
相关资源
最近更新 更多