【问题标题】:Why does the designer refuse to display inherited form?为什么设计师拒绝展示继承的形式?
【发布时间】:2017-11-20 00:10:58
【问题描述】:

我有一个相当成熟的应用程序。它包含一个继承层次结构以促进代码重用,并且在几天前一直运行良好。它在现实世界中完美运行,但我目前无法设计任何继承自其中一种基本形式的形式。

现在,每次我尝试设计一个从 MpvViewBase 继承的表单时,我都会收到以下错误消息:

程序集“CommonForms,版本=1.0.6377.15105,文化=中性,PublicKeyToken=null”的“CommonForms.MvpViewBase”类型中的方法“CloseView”没有实现。

首先,它确实有一个实现,否则代码不会像它完美的那样构建。

其次,显示的版本号并不是适用于dll的版本号。

第三,表单是该 dll 的组成部分,因此不需要对其进行外部引用。

我尝试过的事情:

  1. 清理并重建
  2. 在计算机上搜索每个 CommonForms.dll 并将其删除
  3. 删除组件模型缓存
  4. 将最小值复制到新的解决方案中

这些都没有任何区别。我不明白为什么会发生这种情况,因为自 2012 年以来没有应用相关级别的任何更改。但是,这是一个严重的问题,因为我无法设计任何从 MpvViewBase 继承的表单 - 以及解决方案中的几乎任何表单比消息对话框继承自它!

有人对我下一步应该去哪里解决这个问题有任何建议吗?

编辑

根据要求,下面是基类和第一个继承类的代码。 MvpViewBase 在 Designer 中打开,ControllableViewBase 和任何继承自它的表单都无法打开:

MvpViewBase

public partial class MvpViewBase : MvpFormBase, IView
{

    #region Event Keys

    public EventKey<CancelEventArgs> CompleteRequested { get; private set; }
    public EventKey GenericChangeNotified{ get; private set; }
    public EventKey ShowHelpRequested{ get; private set; }

    #endregion

    #region Private Instance Members

    #endregion

    #region Protected Instance Memebers

    protected Size InitialSize;

    #endregion

    #region Constructors

    public MvpViewBase()
    {
        InitializeComponent();
        if (AppCommon.RunningFromVisualStudioDesigner)
        {
            return;
        }

        InitialiseLocal();
    }

    #endregion

    #region Form Events

    protected override void OnClosing(CancelEventArgs e)
    {
        var args = new CancelEventArgs();
        CompleteRequested.Raise(this, args);

        e.Cancel = args.Cancel;

        base.OnClosing(e);
    }

    private void MvpViewBaseLoad(object sender, EventArgs e)
    {
        FormControl.SetCharacterCase(this, (CharacterCasing) CompanySettings.Instance.CharacterCase);
        MinimumSize = InitialSize;
    }

    #endregion

    #region Methods

    ///<summary>
    /// Closes the form
    ///</summary>
    public void CloseView()
    {
        CloseView(MessageResult.None);
    }

    public void CloseView(MessageResult result)
    {
        if (InvokeRequired)
        {
            Invoke((MethodInvoker)(() => CloseView(result)));
            return;
        }

        if (result > MessageResult.None)
        {
            DialogResult = (DialogResult) result;
        }

        Close();
    }

    ///<summary>
    /// Displays a File Open dialog
    ///</summary>
    ///<param name="config">A FileOpenConfiguration object</param>
    ///<returns>A RequestReponse (string[]) object containing the result</returns>
    public DataRequestResponse<string[]> GetOpenFileNames(FileOpenConfiguration config)
    {
        return FormManager.GetOpenFileNames(config);
    }

    ///<summary>
    /// Displays a File Save dialog
    ///</summary>
    ///<param name="config">A FileSaveConfiguration object</param>
    ///<returns>A RequestReponse (string) object containing the result</returns>
    public DataRequestResponse<string> GetSaveFileName(FileSaveConfiguration config)
    {
        return FormManager.GetSaveFileName(config);
    }

    private void InitialiseLocal()
    { 
        InitialiseEvents();
    }

    protected virtual void InitialiseEvents()
    {
         CompleteRequested = new EventKey<CancelEventArgs>(Events);
         GenericChangeNotified = new EventKey(Events);
         ShowHelpRequested = new EventKey(Events);
    }

    ///<summary>
    /// Sets the text in the dialog title bar
    ///</summary>
    ///<param name="caption">A string representing the caption text to display</param>
    public void SetCaption(string caption)
    {
        if (IsDisposed)
        {
            return;
        }

        if (InvokeRequired)
        {
            MethodInvoker del = () => SetCaption(caption);
            Invoke(del);
            return;
        }

        Text = caption;
    }

    #endregion

}

可控视图基础:

public partial class ControllableViewBase : MvpViewBase, IControllableView
{

    #region Event Keys

    public EventKey CloseRequested { get; private set; }
    public EventKey InitialiseCompleteNotified { get; private set; }
    public EventKey OkRequested { get; private set; }
    public EventKey RevertRequested { get; private set; }
    public EventKey SaveRequested { get; private set; }

    #endregion

    #region Properties

    public bool CloseOptionEnabled
    {
        get { return closeButton.Enabled; }
        set { closeButton.Enabled = value; }
    }

    public bool HelpOptionEnabled
    {
        get { return helpButton.Enabled; }
        set { helpButton.Enabled = value; }
    }

    public bool OkOptionEnabled
    {
        get { return okButton.Enabled; }
        set { okButton.Enabled = value; }
    }

    public bool RevertOptionEnabled
    {
        get { return revertButton.Enabled; }
        set { revertButton.Enabled = value; }
    }

    public bool SaveOptionEnabled
    {
        get { return saveButton.Enabled; }
        set { saveButton.Enabled = value; }
    }

    #endregion

    #region Constructors

    ///<summary>
    /// The Form Constructor
    ///</summary>
    public ControllableViewBase()
    {
        InitializeComponent();

        if (AppCommon.RunningFromVisualStudioDesigner)
        {
            return;
        }

        Initialise();
    }

    #endregion

    #region Methods

    private void ControllableViewLoad()
    {
        SetButtonLocations();
    }

    private void HookEvents()
    {
        Load += (sender, args) => ControllableViewLoad();
        closeButton.Click += (sender, e) => CloseRequested.Raise(this);
        helpButton.Click += (sender, e) => ShowHelpRequested.Raise(this);
        okButton.Click += (sender, e) => OkRequested.Raise(this);
        revertButton.Click += (sender, e) => RevertRequested.Raise(this);
        saveButton.Click += (sender, e) => SaveRequested.Raise(this);
    }

    protected void Initialise()
    {
        InitialiseLocalEvents();
        HookEvents();
    }

    private void InitialiseLocalEvents()
    {
        CloseRequested = new EventKey(Events);
        InitialiseCompleteNotified = new EventKey(Events);
        OkRequested = new EventKey(Events);
        RevertRequested = new EventKey(Events);
        SaveRequested = new EventKey(Events);
    }


    protected virtual void SetButtonLocations()
    {
        int buttonCount = footerPanel.Controls.OfType<Button>().Count();
        const int buttonWidth = 75;
        const int gap = 6;

        int totalWidth = buttonCount * buttonWidth + (gap * buttonCount - 1);
        int left = footerPanel.Width - totalWidth - 6;

        okButton.Left = left;
        left += buttonWidth + gap;
        saveButton.Left = left;
        left += buttonWidth + gap;
        closeButton.Left = left;
        left += buttonWidth + gap;
        revertButton.Left = left;
        left += buttonWidth + gap;
        helpButton.Left = left;
    }

    #endregion

}

接口定义了代码中的事件和方法,但如果需要我可以发布它们...

感谢您寻找并提供任何帮助。

编辑 2

这是来自错误的调用堆栈,以防它有助于为任何人提供任何线索:

此错误的实例(一)

at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at Microsoft.VisualStudio.Design.VSTypeResolutionService.AssemblyEntry.Search(String fullName, String typeName, Boolean ignoreTypeCase, Boolean allowPrivate, Assembly& assembly, String description)
at Microsoft.VisualStudio.Design.VSTypeResolutionService.AssemblyEntry.Search(String fullName, String typeName, Boolean ignoreTypeCase, Assembly& assembly, String description)
at Microsoft.VisualStudio.Design.VSTypeResolutionService.SearchProjectEntries(AssemblyName assemblyName, String typeName, Boolean ignoreTypeCase, Assembly& assembly)
at Microsoft.VisualStudio.Design.VSTypeResolutionService.SearchEntries(AssemblyName assemblyName, String typeName, Boolean ignoreCase, Assembly& assembly, ReferenceType refType)
at Microsoft.VisualStudio.Design.VSTypeResolutionService.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, ReferenceType refType)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.AggregateTypeResolutionService.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.AggregateTypeResolutionService.GetType(String name)
at System.ComponentModel.Design.DesignerHost.System.ComponentModel.Design.IDesignerHost.GetType(String typeName)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.EnsureDocument(IDesignerSerializationManager manager)
at System.ComponentModel.Design.Serialization.CodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager manager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.PerformLoad(IDesignerSerializationManager serializationManager)
at Microsoft.VisualStudio.Design.Serialization.CodeDom.VSCodeDomDesignerLoader.DeferredLoadHandler.Microsoft.VisualStudio.TextManager.Interop.IVsTextBufferDataEvents.OnLoadCompleted(Int32 fReload)  

【问题讨论】:

  • 您必须向我们展示一些代码。特别是 MpvViewBase 的代码和一个继承自它的示例。 我对它们中的任何一个是否是泛型类特别感兴趣。
  • 1.0.6377.15105 是一个非常可怕的版本号。是的,当构建系统更改它时很容易致命,立即使基类无效。找到程序集的 AssemblyInfo.cs 文件并将 [AssemblyVersion] 属性从“1.0.*”更改为更合理的值,例如“1.1.0.0”。谷歌“语义版本控制”是一个不错的策略。
  • 它是一个自动生成的版本号,由"1.0.*"生成。你可以搜索一下。
  • 设计师是一个复杂但又愚蠢的野兽。为了显示您的表单,它实际上创建 base 类对象。之后,它根据 Designer.cs 文件中的 IniializeComponent 的反序列化(原文如此!)代码构建视图的模型或原型。如果基础是框架中的 Window 或 UserControl 等,则没问题 - 它的代码将简单地从框架中加载。但是,如果基类是 Your 类,则它不能“仅加载”基类代码。它默默地编译它(可能是 /obj 文件夹),并加载它,以便它可以用它来为你显示东西。
  • @mjwills:是的,我们做到了(或者至少尽可能干净,因为这是一个拥有数百万行代码和 123 个项目的主要应用程序,仅在主应用程序中就不用管库和测试解决方案)。我会看看我们是否可以做一个绝对干净的解决方案,并只添加这些表单及其祖先的代码,看看会发生什么。不过,这不会是一件微不足道的工作……我会回来报告的。

标签: c# winforms visual-studio


【解决方案1】:

我发布这个答案是为了完整性,以防万一它对其他人有帮助,因为它对我有用,但我不知道为什么......

我创建了一个测试解决方案并将有问题的文件单独放入其中,并且我注释掉了所有并非源自框架的代码。那时我能够激发设计师的热情。

接下来我一次一点地取消所有代码的注释,它仍然有效。我将文件复制回原始解决方案,但它仍然无法正常工作。

下一阶段是从测试解决方案中复制项目文件,此时它确实可以工作,但当然,项目中的所有其他文件不再是项目的一部分。为了找出原因,我一次一个地添加了文件,每次都检查设计器在添加文件后是否仍然有效。

我必须处理一些小的连锁效应,但基本上我现在有了一个完整的解决方案,可以像往常一样在设计器中打开表单。

这是否纯属巧合(例如,MS 可能同时进行了后台软件修复)或者它是否实际上是错误的项目文件,我无法说。但是,如果其他人遇到了与我类似的问题,并且在我的情况下,StackOverflow 和 Google 上的其他解决方案都没有奏效,那么可能值得遵循相同的模式,看看它是否有帮助......

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-11-23
    • 2011-01-19
    • 1970-01-01
    • 2013-07-21
    • 1970-01-01
    • 2021-05-31
    • 1970-01-01
    • 2018-07-04
    相关资源
    最近更新 更多