Наконец будет выполняться независимо от того, что, таким образом, это не имеет значения.
Есть много способов сделать это в зависимости от ваших требований.
DataGridView
, реализующего интерфейс для выполнения пользовательской логикивиртуальными
методами вместо использования абстрактного
классаВам придется выбрать вариант, который лучше всего подходит для ваших нужд. Не зная области и специфики, в которой задан ваш вопрос, я не думаю, что мы можем дать вам 100% определенный ответ.
Ознакомьтесь с этим методом , чтобы узнать, как создать два необходимых атрибута.
Вам понадобится следующий атрибут и класс дескриптора типа (код взят из UrbanPotato)
// Source : taken from http://www.urbanpotato.net/default.aspx/document/2001 Seem to be down
// Allow the designer to load abstract forms
namespace YourNamespace
{
// Place this attribute on any abstract class where you want to declare
// a concrete version of that class at design time.
[AttributeUsage(AttributeTargets.Class)]
public class ConcreteClassAttribute : Attribute
{
Type _concreteType;
public ConcreteClassAttribute(Type concreteType)
{
_concreteType = concreteType;
}
public Type ConcreteType { get { return _concreteType; } }
}
// Here is our type description provider. This is the same provider
// as ConcreteClassProvider except that it uses the ConcreteClassAttribute
// to find the concrete class.
public class GeneralConcreteClassProvider : TypeDescriptionProvider
{
Type _abstractType;
Type _concreteType;
public GeneralConcreteClassProvider() : base(TypeDescriptor.GetProvider(typeof(Form))) { }
// This method locates the abstract and concrete
// types we should be returning.
private void EnsureTypes(Type objectType)
{
if (_abstractType == null)
{
Type searchType = objectType;
while (_abstractType == null && searchType != null && searchType != typeof(Object))
{
foreach (ConcreteClassAttribute cca in searchType.GetCustomAttributes(typeof(ConcreteClassAttribute), false))
{
_abstractType = searchType;
_concreteType = cca.ConcreteType;
break;
}
searchType = searchType.BaseType;
}
if (_abstractType == null)
{
// If this happens, it means that someone added
// this provider to a class but did not add
// a ConcreteTypeAttribute
throw new InvalidOperationException(string.Format("No ConcreteClassAttribute was found on {0} or any of its subtypes.", objectType));
}
}
}
// Tell anyone who reflects on us that the concrete form is the
// form to reflect against, not the abstract form. This way, the
// designer does not see an abstract class.
public override Type GetReflectionType(Type objectType, object instance)
{
EnsureTypes(objectType);
if (objectType == _abstractType)
{
return _concreteType;
}
return base.GetReflectionType(objectType, instance);
}
// If the designer tries to create an instance of AbstractForm, we override
// it here to create a concerete form instead.
public override object CreateInstance(IServiceProvider provider, Type objectType, Type[] argTypes, object[] args)
{
EnsureTypes(objectType);
if (objectType == _abstractType)
{
objectType = _concreteType;
}
return base.CreateInstance(provider, objectType, argTypes, args);
}
}
}
Назначьте их вашей абстрактной форме следующим образом:
[TypeDescriptionProvider(typeof(GeneralConcreteClassProvider))]
[ConcreteClass(typeof(MyAbstractConcreteForm))]
public abstract partial class MyAbstractForm : Form
{
}
Создайте новый класс, который будет унаследован от вашей абстрактной формы. Этот класс будет создан Visual Studio
public class MyAbstractConcreteForm: MyAbstractForm
{
public MyAbstractConcreteForm() : base() { }
}
. Это должно работать.
У меня та же проблема.
Эта страница может вам помочь, хотя это всего лишь обходной путь: Наследование формы от абстрактного класса (и обеспечение ее работы в конструкторе) .
Я не нашел лучшего решения, но, похоже, нет. Так что действительно Windows Forms Designer заставляет вас адаптировать дизайн вашего класса.