C# Visual studio 2008 IDE未正确呈现自定义控件

C# Visual studio 2008 IDE未正确呈现自定义控件,c#,visual-studio-2008,custom-controls,C#,Visual Studio 2008,Custom Controls,在Visual Studio 2008中,我的所有窗体和自定义控件在设计时都有问题。在上次签入之前,所有控件都按预期呈现。当前版本与以前工作版本之间唯一的主要区别是控件UIText上的属性已从Content重命名为Value。其他更改是添加一个新表单和3个新枚举,但肯定没有明显的更改会影响程序中的所有表单(包括新表单) 所有控件(在每个窗体上)现在都呈现为带有控件名称的框(但是它们在运行时都正确呈现): 我在我的项目中尝试创建一个全新的表单,创建一个全新的自定义控件,上面只有一个标签,但我仍然

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

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

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

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

如果从存储库中恢复以前的版本,则所有内容都将重新开始正确渲染:

我可以恢复到这个工作版本并继续,但我更希望知道如果问题再次出现,如何修复它。我在这里发帖,希望这是一个与Visual Studio 2008版(顺便说一下,SP1版)类似的编程问题

更新-跟踪问题,无法解释 我解决了这个问题。嗯,fixed这个词不太合适。我通过一次删除所有用户控件1,直到窗体再次正确呈现,找到了问题所在。问题出在我的签名控制中(它已经存在多年了,只是在我最近的签入中,我在主项目中添加了对项目
ivirtardocket.codebrary
的引用:

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

    }

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

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

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

(更奇怪的是,我甚至还没有使用此属性。)

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

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

请参见


您可能还想进行通读

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

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

当组件的设计器端(UserControl、Form、component)无法在Visual studio designer编辑器中呈现时,请分别在构造函数中调用它们…

。 将“类图”添加到项目中的简单方法是,项目上下文菜单(右键单击项目名称),查看类图。 编辑类的自定义属性(见图),自动在“DesignTimeAttributes.xmta”中添加条目,我们也可以为“Properties”设置自定义属性。

正如我在上面所评论的,LicenseManager类在“NETCF”中是不可争议的。 然后我们可以使用以下方法:

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

    return ret;
}
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)甚至还有其他错误

最后一个选项是,您可以像在(“C:\Users\anton\appData\Local\Microsoft\CoreCon\1.0”)中一样清理appData中的CoreCon文件夹,将“anton”更改为您的用户名。 (在此之前关闭visual studio)

希望这可以帮助任何人,netcf是不推荐和缺乏文档


antonio

尝试启动VS的第二个实例,对所有抛出的异常设置中断。连接到VS的第一个实例。现在加载显示问题的项目。查看是否捕获任何异常。CodeLibrary.Conversions.ImageToByteArray与ConvertImageToByteArray的方法不同。@Phil-这是相同的方法,只是一个输入错误。我不支持ose您可以发布一个完整(但精简)的解决方案来演示问题,可以吗?我会尽快尝试编写一个repo。嗨,这不是WPF。它是Visual Studio 2008中的WM6(Compact Framework)。这不是问题所在,因为正如我所说的,属性已经没有被调用(在我的构造函数中或任何地方)。哦,好的,很抱歉,我帮不上忙。在使用
DllImport
时,我又遇到了同样的问题。我所要做的就是创建DesignTimeAttributes.xmta文件,并修复了它和以前的问题。@DRapp,xmta设置很好,但是.NET Compact Framework(.netcf)中没有“LicenseManager”类。该项目无法编译。我将对此给出另一个答案。