WPF - 如何消除设计时错误提示

4
在设计时,我遇到了几个虚假错误,似乎是由于WPF无法在不实际运行它们的情况下估计事物的值所导致的。当然,在运行时这个问题可以完美解决。 问题是如何消除这些错误?
以下是一个例子:
在一个类中,我有以下两个内容:
public static bool IsHubb {get; set;} 
public static bool IsEC { get { return !IsHubb; } }

以下转换器完美运行:
   public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (HubbCostOfferPage.IsHubb && HubbCostOfferPage.CarObj.TestApprovedDate == null)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

然而,下面的代码(虽然非常相似)却会产生“Object reference not set to an instance of an object.”错误,这意味着如果不将StaticResource定义注释掉,在设计时我只能看到一个大错误。
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
    if (HubbCostOfferPage.IsEC == true && HubbCostOfferPage.CarObj.TestApprovedDate == null)
        return Visibility.Visible;
    else
        return Visibility.Collapsed;
}

如果我将HubbCostOfferPage.IsEC替换为HubbCostOfferPage.IsHubb,所有内容都正常工作,所以我知道问题就在这里。
如果我在转换器中将HubbCostOfferPage.IsEC替换为!HubbCostOfferPage.IsHubb,我会遇到同样的问题。设计师似乎因为无法在设计时计算"!"而抱怨。
有什么办法让这个在设计时也能正常工作吗?
3个回答

2

根据Paul的回答,我建议不要检查CarObj是否为空,因为在运行时会抛出异常。

我建议将您的转换器更改如下:

public object Convert(object value, Type targetType, object parameter,  
  System.Globalization.CultureInfo culture)  
{  
  if (ApplicationIsInDesignMode) { return Visibility.**WHATEVER YOU LIKE ***; }
  if (HubbCostOfferPage.IsEC == true && HubbCostOfferPage.CarObj.TestApprovedDate == null)
    return Visibility.Visible;
else
    return Visibility.Collapsed;
}

private static bool ApplicationIsInDesignMode
    {
        get { return (bool)(DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue); }
    }

你能澄清一下你所说的“在运行时应该抛出异常”是什么意思吗?我很好奇为什么你认为在运行时检查 null 会导致异常。 - Paul Walls
@Paul:在设计时,一些对象可能为空,因为工厂或其他东西没有被调用,所以属性为空。我认为这是可以的。但在运行时,属性不应该为空。因此,我认为检查这个属性的责任不在转换器身上。当然,在某些情况下,对象可能为空,而转换器不应该抛出异常。 - WaltiD
你的解决方案的好处在于它也可以用来解决其他问题。谢谢! :-) - Keren

1

关闭设计师 - 它会带来更多麻烦。将 .xaml 文件与代码编辑器关联(右键单击,选择“打开方式”,然后设置为默认),您将获得更快的体验并仍然拥有智能感知。您可以在需要时使用 Blend。


它并没有确切回答这个问题,但对于一般情况来说,这是最好的建议。 - Steve Greatrex
我更喜欢这个设置:工具 / 选项 / 文本编辑器 / XAML / 其他 -> 始终在完整的 XAML 视图中打开文档 已勾选。 - user604613
@Kent 目前还没有,因为我对完整的 XAML 视图非常满意,但是看到你对此非常热情,下次我在 WPF 项目上时会尝试一下。 - user604613
@Kent:谢谢你的回答。如果我没有使用设计师,我根本不会遇到这个问题,因为只有设计师显示错误,只要我忽略它,我就没有问题。也就是说,这并没有帮助。 - Keren
@UrbanEsc:感谢您的回答。这正是我正在寻找的那种解决方案,即在设置中进行调整。不幸的是,我尝试了您的解决方案,但似乎对错误信息没有任何影响。 :-( - Keren

0
public object Convert(/*snipped*/)
{
#if DEBUG
    if (System.Diagnostics.Process.GetCurrentProcess().ProcessName == "devenv")
        return Visibility.Visible;
#endif
    if (HubbCostOfferPage.IsEC == true && HubbCostOfferPage.CarObj.TestApprovedDate == null)
        return Visibility.Visible;
    else
        return Visibility.Collapsed;
}

编辑:仔细看后,设计师很可能是抱怨 HubbCostOfferPage.CarObj 为空。您可以通过更改代码来解决此问题:

public object Convert(/*snipped*/)
{
    if (HubbCostOfferPage.IsEC && 
        HubbCostOfferPage.CarObj != null &&
        HubbCostOfferPage.CarObj.TestApprovedDate == null)
        return Visibility.Visible;
    else
        return Visibility.Collapsed;
}

这将产生更好的生产代码副作用。

根据您的评论进行第二次编辑,因为这需要代码:

正如我所写的,用 IsHubb 替换 IsEC 可以解决问题,并且在 IsEC 前面加上 ! 会导致问题,因此绝对不是 CarObj 的问题。

在启动时,IsHubb 被初始化为 false。C# 短路布尔逻辑,因此在以下情况下:

if (HubbCostOfferPage.IsHubb && ...

逻辑与运算符后面的所有内容都不会被计算。当您将代码更改为:

if (HubbCostOfferPage.IsEC == true && ...

&&之后的所有内容都正在被评估。像bool这样的整数类型不会成为“对象引用未设置为对象实例”的目标,显然HubbCostOfferPage不为null,所以问题很可能是CarObj。没有看到你的代码,这只是一个建议性的想法。

关于您问题的第二部分,DEBUG指令只是在编译发布模式时编译出执行设计检查的代码。如果您在发布模式下进行任何设计时编辑,可以删除它们。您需要的部分是两者之间的所有内容。


正如我所写的,用IsHubb替换IsEC可以解决问题,而在IsEC前加上!会导致问题,因此绝对不是CarObj出了问题。因此第二个解决方案无法帮助。 至于您的第一个解决方案-我不确定我是否理解正确:如果我正在项目上工作并使用Debug编译,那么这是否意味着将执行Debug部分?在这种情况下,它不能解决问题,因为在工作时运行应用程序时它会表现出错误。 - Keren
我编辑了我的答案以更全面地回答,但是任何一段代码都应该适用于您。 - Paul Walls
谢谢您抽出时间回答。您说的一切都有很多道理,这就是为什么这个问题让我困扰了这么久的原因。我已经完全将ObjCar从转换器中删除,只是为了检查您是否正确,但可悲的是 - 您是错的。这与CarObj无关:即使在转换器中没有提到CarObj,错误仍然存在,但一旦IsEC消失,错误就消失了。这非常奇怪,因为您确实说它甚至无法为null。 - Keren
关于您对DEBUG的回答,正如我所怀疑的那样。这意味着如果我使用该解决方案,我将在开发(=在DEBUG中编译)时遇到问题,而在发布模式下甚至不存在这些问题。这不是一个好主意。 - Keren
那么,如果你将代码块改为 if (HubbCostOfferPage.IsEC),去掉第二个检查,你还是会得到错误吗? - Paul Walls
你尝试添加了DEBUG指令吗?我发的代码影响设计师。当你真正运行应用程序时,无论是Debug还是Release,它都会表现相同。 - Paul Walls

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接