5

我在设计时遇到了 Visual Studios 2008 中的所有表单和自定义控件的问题。在上次签入之前,所有控件都按预期呈现。当前版本和以前的工作版本之间的唯一主要区别是控件上的属性UIText从 重命名ContentValue。其他更改是添加了一个新表单和 3 个新枚举,但肯定没有明显的更改会影响程序中的所有表单(包括新表单)。

所有控件(在每个窗体上)现在呈现为带有控件名称的框(但是它们都在运行时正确呈现):

渲染问题

我尝试在我的项目中创建一个全新的表单,创建一个只有一个标签的全新自定义控件,但我仍然遇到完全相同的问题:

离奇

请注意,标准的 .Net 表单控件可以正常工作,因此这只是自定义控件的问题。

如果我从存储库中恢复我以前的版本,那么一切都会重新开始正确呈现:

正确渲染

我可以恢复到这个工作版本并继续,但我宁愿知道如果问题再次发生如何解决。我在这里发帖希望这是一个与 Visual Studios 2008 问题相对的编程问题(顺便说一下,在 SP1 上)。

更新 - 跟踪问题,无法解释

解决了这个问题。好吧,固定并不是真正的正确词。我通过一次删除所有用户控件 1 来定位问题,直到表单再次开始正确呈现。问题出在我的签名控件中(它已经存在了很长时间,只有在我最近一次签到时,我才iVirtualDocket.CodeLibrary在主项目中添加了对该项目的引用:

  iVirtualDocket
    - References iVirtualDocket.UIControls
    - References iVirtualDocket.CodeLibrary
  iVirtualDocket.UIControls
    -References iVirtualDocket.CodeLibrary

签名有一个名为 的属性SignatureData,它正在执行此操作:

public byte[] SignatureData
{
    get
    {
        if (_signature == null)
        {
            return null;
        }
        else
        {
            return iVirtualDocket.CodeLibrary.Conversions.ImageToByteArray(
                _signature, ImageFormat.Png);
        }
    }
}

ImageToByteArray 如下所示:

public static byte[] ImageToByteArray(Image imageToConvert,
        ImageFormat formatOfImage)
{
    byte[] ret;
    using (MemoryStream ms = new MemoryStream())
    {
        imageToConvert.Save(ms, formatOfImage);
        ret = ms.ToArray();
    }

    return ret;
}

如果我将上述方法移到UIControls项目中,那么一切正常。但是,一旦我将该方法放回CodeLibrary项目中并在那里调用它,我的所有表单都会停止呈现用户控件。

因此,执行以下操作可以解决问题,但我真的很想知道原因:

public byte[] SignatureData
{
    get
    {
        if (_signature == null)
        {
            return null;
        }
        else
        {
            // Need to call this code directly here instead of through 
            // the CodeLibrary conversions, otherwise all user controls stop 
            // rendering in design mode
            byte[] ret;
            using (MemoryStream ms = new MemoryStream())
            {
                _signature.Save(ms, ImageFormat.Png);
                ret = ms.ToArray();
            }

            return ret;
        }
    }
}

(更奇怪的是我还没有使用这个属性。)

4

3 回答 3

2

我们有一个应用程序有类似的非设计时显示问题。通过做一些研究(我不记得我们在哪里找到它),我们最终创建了一个文件

设计时间属性.xmta

它的类型是“设计时属性文件”的类型

在其中,我们只需要声明我们定义的每个控件类并将其限定为“DesktopCompatible”。通过这种方式,它显然告诉设计者可以绘制,并且某些控件中的实际功能(对我们来说也是手持扫描仪上的签名控件)实际上会在运行时调用设计器中不可用的东西。该文件的内容类似于...

<?xml version="1.0" encoding="utf-16"?>
<Classes xmlns="http://schemas.microsoft.com/VisualStudio/2004/03/SmartDevices/XMTA.xsd">
  <Class Name="MyNamespace.MyControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>

  <Class Name="MyNamespace.MyOtherControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>

  <Class Name="AnotherNamespace.MySignControl">
    <DesktopCompatible>true</DesktopCompatible>
  </Class>
</Classes>

这也是对提供 csauve 答案的评论的补充。如果您的构造函数试图初始化与设备相关的东西并因此引发错误,因为设计时显然没有设备 dll、控件或任何可能/将在设计时杀死该控件的东西。我们创建了两个静态函数来测试任何一种方式

public static bool IsDesignTime()
{
  return System.ComponentModel.LicenseManager.UsageMode ==
         System.ComponentModel.LicenseUsageMode.Designtime;
}

public static bool IsRunTime()
{
  return System.ComponentModel.LicenseManager.UsageMode ==
         System.ComponentModel.LicenseUsageMode.Runtime;
}

并在构造函数中分别调用它们......

于 2012-04-13T18:54:03.473 回答
0

我想也许你需要让你的控件知道它们何时处于设计模式。如果可以避免,您的控件的无参数构造函数不应执行任何昂贵或具有副作用的操作(即从磁盘加载文件)。

我通过您的屏幕截图假设您正在使用 WPF。我相信可以使用 DesignerProperties.GetIsInDesignMode(this) 确定设计模式,

请参阅http://msdn.microsoft.com/en-us/library/system.componentmodel.designerproperties.getisindesignmode.aspx

public partial class MyControl : UserControl
{
   public MyControl()
   {
      InitializeComponent();
      if (!DesignerProperties.GetIsInDesignMode(this))
      {
        //Do expensive operations here
      }
   }
}

您可能还想阅读http://blogs.msdn.com/b/jgalasyn/archive/2007/10/29/troubleshooting-wpf-designer-load-failures.aspx

于 2012-04-13T16:44:15.883 回答
0

当您的组件(用户控件、表单、组件)的设计器端无法在 Visual Studio 设计器编辑器中呈现时。在项目中添加“ClassDiagram”的简单方法,项目上下文菜单(右键单击项目名称),查看类图。编辑类的自定义属性(见图),在“DesignTimeAttributes.xmta”中自动添加条目,我们也可以为“Properties”设置自定义属性。 类图/xmta 向属性添加自定义属性

正如我在上面评论的那样,LicenseManager 类在“NETCF”中是不可用的。然后我们可以使用以下内容:

using System;
using System.Linq;
using System.Collections.Generic;
using System.Text;

namespace SmartDeviceCommon
{
    public static class SmartDeviceApplication
    {
        public static bool DesignTime
        {
            get
            {
                return Environment.OSVersion.Platform != PlatformID.WinCE;
            }
        }

        public static bool RunTime
        {
            get
            {
                return Environment.OSVersion.Platform == PlatformID.WinCE;
            }
        }

        public static bool IsDesignTime()
        {
            // Determine if this instance is running against .NET Framework by using the MSCoreLib PublicKeyToken
            System.Reflection.Assembly mscorlibAssembly = typeof(int).Assembly;
            if ((mscorlibAssembly != null))
            {
                if (mscorlibAssembly.FullName.ToUpper().EndsWith("B77A5C561934E089"))
                {
                    return true;
                }
            }
            return false;
        }

        public static bool IsRunTime()
        {
            // Determine if this instance is running against .NET Compact Framework by using the MSCoreLib PublicKeyToken
            System.Reflection.Assembly mscorlibAssembly = typeof(int).Assembly;
            if ((mscorlibAssembly != null))
            {
                if (mscorlibAssembly.FullName.ToUpper().EndsWith("969DB8053D3322AC"))
                {
                    return true;
                }
            }
            return false;
        }

    }

}

如果不起作用,则使用@Phil 的第一条评论:启动具有管理员权限的 Visual Studio 的另一个实例,附加到第一个实例,使用第一个实例,双击您的自定义用户控件到设计器加载,未渲染的组件可以包含特定于平台的调用 (dllimport) 甚至其他错误。

最后一个你可以清理 appData 中的 CoreCon 文件夹,如 ("C:\Users\anton\AppData\Local\Microsoft\CoreCon\1.0"),将 'anton' 更改为你的用户名。(在此之前关闭视觉工作室)。

希望这可以帮助任何人,netcf 已被弃用且缺乏文档

安东尼奥

于 2020-03-03T01:34:15.017 回答