设计者必须创建一个...不能的实例,因为该类型被声明为抽象
Posted
技术标签:
【中文标题】设计者必须创建一个...不能的实例,因为该类型被声明为抽象【英文标题】:The designer must create an instance of...cannot because the type is declared abstract 【发布时间】:2010-10-03 15:17:43 【问题描述】:Visual Studio 抱怨:警告 1 设计者必须创建一个类型为“RentalEase.CustomBindingNavForm”的实例,但它不能,因为该类型被声明为抽象。
Visual Studio 不允许我访问表单的设计器。该类已经实现了 CustomBindingNavForm 中的所有抽象方法。 CustomBindingNavForm 提供了一些具体和抽象的功能。
有没有办法解决这个问题?
这是课程:
public abstract class CustomBindingNavForm : SingleInstanceForm
//Flags for managing BindingSource
protected bool isNew = false;
protected bool isUpdating = false;
/// <summary>
/// This is so that when a new item is added, it sets isNew and firstPass to true. The Position Changed Event will look for
/// firstPass and if it is true set it to false. Then on the next pass, it will see it's false and set isNew to false.
/// This is needed because the Position Changed Event will fire when a new item is added.
/// </summary>
protected bool firstPass = false;
protected abstract bool validateInput();
protected abstract void saveToDatabase();
//manipulating binding
protected abstract void bindingSourceCancelResetCurrent();
protected abstract void bindingSourceRemoveCurrent();
protected abstract void bindingSourceMoveFirst();
protected abstract void bindingSourceMoveNext();
protected abstract void bindingSourceMoveLast();
protected abstract void bindingSourceMovePrevious();
protected abstract void bindingSourceAddNew();
public void bindingNavigatorMovePreviousItem_Click(object sender, EventArgs e)
if (validateInput())
bindingSourceMovePrevious();
else
DialogResult cont = MessageBox.Show(null, "There are errors in your data. Click Cancel to go back and fix them, or ok to continue. If you continue, changes will not be saved.", "Continue?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (cont == DialogResult.OK)
if (isNew)
bindingSourceRemoveCurrent();
isNew = false;
else
bindingSourceCancelResetCurrent();
bindingSourceMovePrevious();
public void bindingNavigatorAddNewItem_Click(object sender, EventArgs e)
if (validateInput())
saveToDatabase();
bool temp = isUpdating;
isUpdating = true;
bindingSourceAddNew();
isUpdating = temp;
isNew = true;
firstPass = true;
else
DialogResult cont = MessageBox.Show(null, "There are errors in your data. Click Cancel to go back and fix them, or ok to continue. If you continue, changes will not be saved.", "Continue?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (cont == DialogResult.OK)
if (isNew)
bindingSourceRemoveCurrent();
isNew = false;
else
bindingSourceCancelResetCurrent();
bool temp = isUpdating;
isUpdating = true;
bindingSourceAddNew();
isUpdating = temp;
isNew = true;
firstPass = true;
public void bindingNavigatorMoveFirstItem_Click(object sender, EventArgs e)
if (validateInput())
bindingSourceMoveFirst();
else
DialogResult cont = MessageBox.Show(null, "There are errors in your data. Click Cancel to go back and fix them, or ok to continue. If you continue, changes will not be saved.", "Continue?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (cont == DialogResult.OK)
if (isNew)
bindingSourceRemoveCurrent();
isNew = false;
else
bindingSourceCancelResetCurrent();
bindingSourceMoveFirst();
public void bindingNavigatorMoveNextItem_Click(object sender, EventArgs e)
if (validateInput())
bindingSourceMoveNext();
else
DialogResult cont = MessageBox.Show(null, "There are errors in your data. Click Cancel to go back and fix them, or ok to continue. If you continue, changes will not be saved.", "Continue?", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2);
if (cont == DialogResult.OK)
if (isNew)
bindingSourceRemoveCurrent();
isNew = false;
else
bindingSourceCancelResetCurrent();
bindingSourceMoveNext();
【问题讨论】:
How can I get Visual Studio 2008 Windows Forms designer to render a Form that implements an abstract base class?的可能重复 【参考方案1】:我还没有看到城市土豆的内容(它已关闭),但我和Smelch 想出了一个解决方案。 Form
本身继承自一个抽象类,所以他们没有告诉你的是,它只是第一级不能抽象的继承,第二级往下可以。强>
从那里开始,只需在中间有一个空类并在表单声明周围包裹一个#if debug
,你就可以开始了。只要确保在发布模式下发布并在调试模式下设计(这是非常典型的)。
您将在设计(调试)和构建(发布)时获得完整的设计器支持和真正的抽象基类,因为每次它最终都会使用您的抽象基类。
The full explanation and answer is here
【讨论】:
【参考方案2】:您可以使用抽象类上的属性来解决此问题,如下所示
[TypeDescriptionProvider(typeof(AbstractControlDescriptionProvider<MyBaseFormEf, Form>))]
这适用于您需要的所有情况。 AbstractControlDescriptionProvider 在下面
public class AbstractControlDescriptionProvider<TAbstract, TBase> : TypeDescriptionProvider
public AbstractControlDescriptionProvider()
: base(TypeDescriptor.GetProvider(typeof(TAbstract)))
public override Type GetReflectionType(Type objectType, object instance)
if (objectType == typeof(TAbstract))
return typeof(TBase);
return base.GetReflectionType(objectType, instance);
public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
if (objectType == typeof(TAbstract))
objectType = typeof(TBase);
return base.CreateInstance(provider, objectType, argTypes, args);
【讨论】:
有时设计师仍然无法使用这种方法。我总是必须重新启动 VS 来修复它。我想知道是否还有其他方法。 SZT - 是的,我也遇到过这个问题。我向微软报告了它,他们说它没有影响足够多的人来保证修复,他们可以复制它 鉴于每天使用 winform 的人数较少,这是可以理解的,如果有机会,我宁愿将这个项目转移到 wpf。对于 winform 用户来说仍然很烦人。 是的 - 这里也一样。我的项目太大而无法迁移:(【参考方案3】:这对我来说适用于继承 UserControl 的抽象类
public class AbstractCommunicatorProvider : TypeDescriptionProvider
public AbstractCommunicatorProvider(): base(TypeDescriptor.GetProvider(typeof(UserControl)))
public override Type GetReflectionType(Type objectType, object instance)
return typeof(UserControl);
public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
objectType = typeof(UserControl);
return base.CreateInstance(provider, objectType, argTypes, args);
[TypeDescriptionProvider(typeof(AbstractCommunicatorProvider))]
public abstract partial class SelectorBase : UserControl
///class contents
我不需要将它添加到所有派生类,但在您的情况下您可能需要。
【讨论】:
以上是关于设计者必须创建一个...不能的实例,因为该类型被声明为抽象的主要内容,如果未能解决你的问题,请参考以下文章