【问题标题】:WPF - How to get rid of false design time errorsWPF - 如何摆脱错误的设计时错误
【发布时间】:2011-09-02 17:00:53
【问题描述】:

在设计时我有几个错误的错误,这似乎是由于 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;
    }

然而(尽管非常相似)下面给出了“对象引用未设置为对象的实例”。错误,这意味着我在设计时唯一能看到的没有注释掉 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.IsHubb 替换 HubbCostOfferPage.IsEC,一切正常,所以我知道问题出在哪里。

如果我在转换器中用 !HubbCostOfferPage.IsHubb 替换 HubbCostOfferPage.IsEC,我会遇到同样的问题。设计师似乎在抱怨,因为它无法评估“!”在设计期间。

任何想法如何在设计时也能做到这一点?

【问题讨论】:

    标签: wpf


    【解决方案1】:

    根据 Pauls 的回答,我建议不要检查 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); }
        }
    

    【讨论】:

    • 你能澄清during runtime the exception shall be thrown的意思吗?我很好奇为什么你认为在运行时检查 null 会导致异常。
    • @Paul:在设计期间,某些对象可能为空,因为未调用工厂或其他东西,因此该属性为空。我认为这没关系。但在运行时,该属性不得为空。所以我相信不是转换器负责检查这个。但当然也有可能在某些情况下,对象可以为 null,转换器不会抛出异常。
    • 您的解决方案的伟大之处在于它也可以用来解决其他问题。谢谢! :-)
    【解决方案2】:

    关闭设计器 - 麻烦多于其价值。将 .xaml 文件与代码编辑器相关联(右键单击、打开方式,然后设置为默认值),您将获得更快的体验并且仍然拥有 Intellisense。您可以在需要时使用 Blend。

    【讨论】:

    • 它不能完全回答这个问题,但它是一般情况下的最佳建议
    • 我更喜欢这个:工具 / 选项 / 文本编辑器 / XAML / 其他 -> 选中“始终以完整 XAML 视图打开文档”
    • @Kent 还没有,因为我对完整的 XAML 视图非常满意,但是看到你对它相当热情,我下次在 WPF 项目中尝试一下
    • @Kent:感谢您的回答。如果我不使用设计器,我根本不会遇到这个问题,因为只有设计器会显示错误,所以只要我忽略它,我就没有问题。 IE。 - 这没有帮助。
    • @UrbanEsc:感谢您的回答。这正是我正在寻找的解决方案,在设置中。不幸的是,我尝试了您的解决方案,但似乎对错误消息没有任何影响。 :-(
    【解决方案3】:
    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 && ...
    

    逻辑 And 之后的所有内容都被 NOT 评估。当您将代码更改为:

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

    现在正在评估&& 之后的所有内容。 bool 等整数类型不会成为“对象引用未设置为对象的实例”的目标,显然HubbCostOfferPage 不为空,因此可能的罪魁祸首是 CarObj。没有看到你的代码,这只是一个建议。

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

    【讨论】:

    • 正如我所写的,用 IsHubb 替换 IsEC 可以解决问题,并放置一个 !在 IsEC 导致它之前,所以问题绝对不是 CarObj。因此,第二种解决方案无济于事。至于您的第一个解决方案 - 我不确定我是否正确:如果我正在处理项目并使用 Debug 进行编译,那是否意味着 Debug 是将要执行的部分?在这种情况下,它并不能解决问题,因为它在运行应用程序时会出现错误。
    • 我编辑了我的答案以更全面地回答,但任何一段代码都应该适合你。
    • 感谢您抽出宝贵时间回答。你说的都很有道理,这正是这个问题让我如此困惑的原因。我已经完全从转换器中取出了 ObjCar,只是为了检查您是否有可能是对的,但遗憾的是 - 您错了。这与 CarObj 无关:即使转换器中甚至没有提到 CarObj,但只要 ISEC 离开,错误就会消失。这很奇怪,因为你说得对,它甚至不能为空。
    • 至于你对DEBUG的回答,跟我猜的一模一样。这意味着如果我使用该解决方案,我最终会在开发(= 在 DEBUG 中编译)时遇到问题,这些问题甚至在发布模式下都不存在。不是个好主意。
    • 所以如果你把块改成if (HubbCostOfferPage.IsEC),去掉第二个检查,你还是会得到错误?
    猜你喜欢
    • 1970-01-01
    • 2011-08-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多