【发布时间】:2017-11-20 00:10:58
【问题描述】:
我有一个相当成熟的应用程序。它包含一个继承层次结构以促进代码重用,并且在几天前一直运行良好。它在现实世界中完美运行,但我目前无法设计任何继承自其中一种基本形式的形式。
现在,每次我尝试设计一个从 MpvViewBase 继承的表单时,我都会收到以下错误消息:
程序集“CommonForms,版本=1.0.6377.15105,文化=中性,PublicKeyToken=null”的“CommonForms.MvpViewBase”类型中的方法“CloseView”没有实现。
首先,它确实有一个实现,否则代码不会像它完美的那样构建。
其次,显示的版本号并不是适用于dll的版本号。
第三,表单是该 dll 的组成部分,因此不需要对其进行外部引用。
我尝试过的事情:
- 清理并重建
- 在计算机上搜索每个 CommonForms.dll 并将其删除
- 删除组件模型缓存
- 将最小值复制到新的解决方案中
这些都没有任何区别。我不明白为什么会发生这种情况,因为自 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