【问题标题】:Separating Designers from Main Assembly将设计师与主要装配体分开
【发布时间】:2013-11-11 14:32:31
【问题描述】:

背景

我正在将 SourceForge 上的 TreeViewAdv(TVA) 项目转换为 vb.net。到目前为止,我已经成功地转换了代码,成功地构建了它,将 dll 的引用添加到了新项目中,将控件添加到了工具箱中,将控件添加到了窗体中,并修改了控件的属性。在构建接受 Aga.Controls 命名空间之前,我还在表单中编码了功能。

问题

当我去调试已放置 TVA 控件的应用程序时,我收到错误:''Aga' 未声明。由于其保护级别,它可能无法访问。' 在对该命名空间的所有调用中。所以,我在 SourceForge 上研究了这个问题,这里有一个线程:https://sourceforge.net/p/treeviewadv/discussion/568369/thread/005e61ef/ 讨论了这个问题。据说有人在您看到这样的行为时发现了问题所在,但未能分享他们智慧的任何细节。一般的问题是,当在 2010 项目中引用 2008 年编译的 dll 时'是 VS 2010 要求您将设计师与主程序集分开。'我尝试联系那里的人,但似乎有论坛中的任何主题都没有真正的活动。这引出了我的第一个问题……

问题

1.) 满怀希望,StackOverflow 上是否有人专门为 treeviewadv 项目成功完成了这项工作?如果是这样,我真的很感激对所做工作的详细描述,或者对最终生成的代码/修复的简短描述。虽然我知道这不太可能,但我想在询问有关“如何”的更一般性问题之前先问一下?

2.) 除非任何人符合第一名的要求,否则是否有任何人了解此一般流程并且至少对 TVA 项目有足够的了解并愿意与我合作开展这项工作?

2.) 除了 1 和 2,是否有人在任何项目中完成了此操作,并且可以相对详细地描述一般过程和/或指向示例代码?

3.) 除了 1、2 和 3 之外,是否有一个特别好的资源可供我访问,其中概述了如何以上述方式更新 VS2008 项目?

免责声明

我了解此过程可能过于复杂,无法在此处讨论,因此如果需要,我愿意在其他地方进行讨论/努力。如果第 1 类或第 2 类的人可以(回答我的问题/与我一起工作)并且您认为应该在其他地方进行讨论,请告知我我们如何相互联系,因为似乎没有关于 S.O. 的正式机制。如果可以找到答案,我仍然有兴趣在此处发布(或链接)结果以供所有人分享。

【问题讨论】:

  • by designers 你是指 UI 设计师还是标准的 VS 设计师? (后者看起来很奇怪,但该项目甚至有 UI 设计师吗?)
  • 我感受到你的痛苦。没有什么比谷歌搜索一个问题更糟糕的了,然后找到一个 2008 年写的论坛帖子,最后一篇帖子是“没关系,我修好了!”。你做了什么!!!什么是巫术??!!
  • @Plutonix - 首先,我不能 100% 确定 sourceforge 线程中的用户指的是什么。因此我的问题在这里。最初的 VS2008 解决方案中有 3 个项目:
  • 1.) 树 - 这是实际的控制。它没有在打开时直接显示为 UI 的文件(我假设这就是 UI 设计师的意思)。它确实有一个带有关联设计器文件的文件(TreeViewAdv.Designer.cs,我假设这就是 VS 设计器的意思)。 2.) 一个 UnitTest 项目 - 不需要构建,所以我没有将它导入到我的项目中......所以这不是问题。 3.)一个 SampleApp 项目 - 没有必要构建,所以我没有将它导入我的项目......所以这不是问题。 4.) 不要在工作中搜索 VS 设计师。
  • UI 设计器是为某些控件设置属性而出现的特殊事物。 DataGridView、ListView、ContextMenuStrip 都有丰富的 UI 设计器。 CheckedLstBox 和 ListBox 具有用于编辑初始内容的 UI 设计器。从名字上看,他们很可能在谈论 UI 设计师。如果是这样,则主控件/组件类将具有如下属性装饰:<Designer(GetType(xxxDesigner(Of xxxx)))>,以及与xxxDesigner 匹配的另一个类。听起来您“只是”需要将其移动到自己的程序集中。

标签: c# vb.net visual-studio updates


【解决方案1】:

这里有更多信息解决不同程序集中的设计器的一般问题。有一些警告:首先我(我们?)不确定与 UI 设计器有关的核心问题。鉴于该项目似乎是一个自定义 TreeView,它似乎很可能是这种情况,但术语“设计器”可以以更通用的方式用于此控件。第二个警告是,我所要做的只是上面的描述,还没有看到控件的代码。

也就是说,我刚刚完成了撤消管理器组件的放置(即它继承自 Component 并位于表单托盘中)。它需要的一部分是开发人员选择表单上的控件以进行撤消的方法。布局/构造是这样的:

Imports Plutonix.UIDesigners

Namespace Plutonix.UnDoMgr

Public Class UndoManager
    Inherits Component      
    Implements ISupportInitialize      

    Private _TgtControls As New Collection(Of Control)

    <EditorAttribute(GetType(UnDoControlCollectionUIEditor), _
          GetType(System.Drawing.Design.UITypeEditor))> _
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    Public Property UnDoTargets() As Collection(Of Control)
        Get
            Return _TgtControls
        End Get
        Set(ByVal value As Collection(Of Control))
            If value IsNot Nothing Then
                _TgtControls = value
            Else
                _TgtControls.Clear()
            End If
        End Set
    End Property
    '...

&lt;EditorAttribute... 装饰指定此组件使用名为UnDoControlCollectionUIEditor 的特殊设计器。如果您正在转换的项目在一个或多个属性上没有此属性,则问题可能与 UI 设计师无关。

后来,有用于 CControls 集合编辑器的 UI 编辑器。这是一个单独的类,虽然它在同一个文件中:

  <System.Security.Permissions.PermissionSetAttribute( _
        System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> _
Public Class UnDoControlCollectionUIEditor
    Inherits ControlCollectionUIEditor

    Public Sub New()
        MyBase.bExcludeForm = True
        MyBase.bExcludeSelf = True

       ' create a list of supported control TYPES
        typeList.Add(GetType(TextBox))
        '... 9 more lines adding control types to List(of System.Type)
    End Sub
 End Class

几乎所有代码都位于基类ControlCollectionUIEditor 中,该基类位于不同的程序集(DLL)中。虽然我的组件实际上使用的是本地定义的,但作为测试,我将编辑器更改为 ControlCollectionUIEditor,这是我的设计器 DLL 中的基类。标签、面板、GroupBoxes 等没有/不需要撤消功能,因此我的设计器使它们免于在设计器中显示 - 当我使用基类时,它们都按预期显示在设计器列表中。

所有标准 UI 编辑器(字符串集合编辑器等)都在 NET 程序集中,因此在一个程序集中定义并在另一个程序集中使用(您的/我们的/开发人员的)。几年前,我决定将我编写的几个不同的 UIDesigner 放入 UIDesigner.DLL(即它们自己的程序集)中,它们工作得很好。

除此之外,我对一些细节感到困惑。听起来您正试图在转换中使用这个 2008 程序集(DLL?)。是设计师所在的地方吗?如果是这样,它已经在您的 VS 2010 项目的另一个程序集中,那么为什么会出现问题?是否可以通过转换 2008 年大会中的任何内容来避免整个事情(仍然不清楚其中的内容)。

HTH

编辑

我快速查看了源代码,它至少使用了 1 个 UIDesigner。 TreeViewAdv.Properties.csNodeControlCollectionEditor 定义为 NodeControls 属性的自定义控件集合编辑器。编辑在NodeControlsCollection.cs。巧合的是,它与我的 UnDoManager 所做的完全一样:定义哪些控件类型对 CollectionEditor 有效。然后你的东西调用标准的 NET CollectionEditor,我的调用 CodeProject DialogForm 版本。还有一个StringCollectionEditor.cs 文件,但我不知道那是 UI 设计器还是运行时用户的东西。

既然你有这些代码,你应该能够模仿我上面所做的事情。我还将验证 VS 2010 确实有提到的怪癖。但我也对 2008 年大会的内容感到困惑。有没有你没有来源的作品?您也可以尝试将安全属性添加到项目中的任何 UI 设计器,因为 CS 版本没有它们,并且引用的 msg 表示有关“保护级别”的内容。这似乎不太可能有帮助,但既然你正在处理一个怪癖,谁知道......?

另外,这是一个雄心勃勃的转换项目!

【讨论】:

  • 谢谢,这会让我有更多的工作要做。刚刚为我澄清的一件事是您所说的 UI 设计师...当您按下控件属性上的省略号时弹出的窗口。我很抱歉,但是在 NET 中有很多称为设计师的东西,无法进行搜索并获得您想要的东西。他们的 MS 需要丰富他们的词汇量。
  • 实际上他们的官方 MS 术语是 UIEditor 这是美国倾向于称他们为设计师,因为这是我们在设计时在 VS Designer 中编写的东西。嗯...请随意投票 - 我认为这也可以让您获得积分,因此您可以在需要时开始聊天。
  • 我已经取得了一些进展,但我遇到了一些额外的问题。我已经开始了对话“TreeViewAdv Conversation”。希望在那里见到你。
【解决方案2】:

问题原因已验证

首先,我想指出,确实,在引用的 dll 中丢失命名空间的问题是因为该 dll 中存在自定义 UI 编辑器/设计器。

修复

将自定义编辑器/设计器从“主要”类库中分离出来的一般过程如下:

1.) 查找项目中的所有自定义编辑器/设计师。如果您只是对项目有点熟悉,那么一个好方法是在整个解决方案中查找 (Ctrl + F) 'UITypeEditor'。如果你是设计它的人,那么你应该没有问题。

2.) 删除或注释掉整个自定义编辑器/设计器类。我更喜欢注释掉以简化文档(以防万一您需要返回)。

3.) 在解决方案中创建新项目。如果您看不到解决方案(即您只能看到项目),请转到工具-->选项-->项目和解决方案。在那里,您将看到一个显示“始终显示解决方案”的复选框。显示解决方案后,右键单击并选择 add-->New Project... 可以随便命名,这对代码几乎没有影响。

4.) 在新项目中将 Class1 重命名为方便的名称。在最初保存自定义编辑器/设计器类的文件顶部传输所有“使用”语句。 编辑:为任何命名空间添加 using 语句,使您可以访问主项目所需的类型。 为每个类声明适当的命名空间。将自定义类复制并粘贴到正确的命名空间中(如果需要,您可以将所有自定义编辑器/设计器放在这个文件中)。将任何声明为“内部”的类更改为“公共”(内部只是程序集的范围)。

5.) 如果新项目需要任何引用,请立即添加。如果您的自定义编辑器正在编辑自定义类型,您可能需要对定义这些类型的项目的引用。如果这些类型是在您的“主要”程序集中定义的,这可能会有点棘手,因为它可能会导致循环引用问题。解决此问题的一种方法(可能也是正确的方法)是从主程序集中删除这些类型的声明,并仅为它们的声明创建一个新项目/程序集。如果由于某种原因它们与您的主程序集密不可分,请搁置先前由您的主程序集制作的成功构建 (dll) 并引用它。这会降低代码的未来可持续性,因为这些类型可能会发生,但如果您想要的话,现在就可以完成工作。

6.) 调试自定义编辑器/设计器项目后,构建它并将该项目的构建 (dll) 作为参考添加到主项目/程序集中。

7.) 调试内部,在解决方案中创建一个新项目并将BOTH dll(主编辑器和自定义编辑器)添加到引用中。验证控件/属性在设计时和运行时的行为是否符合预期。

8.) 最后,在外部调试。创建新的解决方案,引用两个 dll,验证功能。在本机解决方案和外部进行调试似乎有点矫枉过正,但我​​发现环境之间的行为存在许多差异。彻底。

重要提示:我花了 LONG 时间确定需要添加两个 dll。您会看到,当仅将主 dll 添加到测试项目时,它的行为就像同时添加了两者一样。我虽然这是合理的(而且相当花哨),因为主程序集引用了另一个程序集。但是,关闭并打开 Visual Studio,它不起作用。长话短说,添加两个 dll。

TreeViewAdv 细节

1.) 有两个自定义 UIEditor。第一个是在 NodeControlsCollection.cs 中称为 NodeControlCollectionEditor,它继承了标准的 .NET CollectionEditor。添加的唯一功能是明确分配允许编辑器使用的控件类型。似乎这在很大程度上是作为一种解决方法来允许将所有 NodeControl 类型添加到集合中(这需要传递类型 NodeControl),但是绕过传递 NodeControl 类型会导致错误的事实,因为您无法实例化抽象类型.第二个是StringCollectionEditor.cs 中的StringCollectionEditor。这也继承了标准的 .NET CollectionEditor 并添加了一些功能(不确定目的)。

2 - 4.)与一般流程相同。

5.) 我目前不得不使用后一种方法(留出 Aga.Controls 的 dll 供我的自定义 UIEditor 参考)。稍后我希望将一些对象声明与主程序集分开,以使解决方案更可靠。

6 - 8.) 在同一个解决方案(即使是不同的项目)中运行测试应用程序时,不会出现原始错误(丢失 aga 命名空间)。此外,一些在外部工作的修复程序在内部没有正确运行,反之亦然。因此,我建议在这两种环境中进行测试。

最终请求 虽然这里回答了我的问题的一般性和具体性,但 Plutonix 的帮助对于我找到解决方案至关重要。虽然我将此标记为答案。我希望人们也支持 Plutonix 的答案,因为他为帮助我找到答案所付出的努力(此外,如果他的答案不太具体,他的答案也是正确的)。

编辑:当我修改原始 TVA C# 代码时,上述过程有效。我什至能够在 VB.net 项目中引用并成功使用生成的 DLL。当我尝试将相同的过程应用于已转换为 VB.net 的 TVA 代码行时,它导致了与我开始时相同的问题。一切正常,直到我去运行应用程序,然后它看不到 aga 命名空间。

编辑解决方案:转到属性(项目丢失参考)--> 编译选项卡--> 高级编译选项按钮。在目标框架下,如果还没有,请更改为“.NET Framework 4”。如果已选择该值,则您可能正在寻找不同的原因。

【讨论】:

  • P.S.:经常清理和重建您的相互引用项目。这也给我带来了一些困难。 . P.P.S.:我会看到让公众可以使用这个代码线,因为它解决了“TreeViewAdv 不适用于 2010”的问题。我也几乎完成了 VB 转换。我会尽可能把它弄出来。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-08-25
  • 1970-01-01
相关资源
最近更新 更多