[英]How to fix the errror 'The designer must create an instance of type " " but cant because it marked abstract"
[英]The designer must create an instance of…cannot because the type is declared abstract
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();
}
}
}
}
我還沒有看到城市土豆的內容(它下來),但我和Smelch想出了一個解決方案。 Form
本身繼承自一個抽象類,所以他們沒有告訴你的是,它只有第一層繼承不能是抽象的,第二層可以。
從那里開始,只需在中間有一個空類並在表單聲明周圍包裝#if debug
,就可以了。 只要確保在發布模式下發布並在調試模式下設計(這是非常典型的)。
您將在設計(調試)和構建(發布)時獲得完整的設計器支持和真正的抽象基類,因為每次最終都會使用您的抽象基類。
您可以使用抽象類上的屬性來解決這個問題,如下所示
[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);
}
}
這對繼承 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
}
我不需要將它添加到所有派生類中,但在您的情況下您可能需要這樣做。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.