Используя Windows Form как абстрактный класс - который шаблон использовать?

Наконец будет выполняться независимо от того, что, таким образом, это не имеет значения.

10
задан Jon Seigel 4 March 2010 в 20:47
поделиться

3 ответа

Есть много способов сделать это в зависимости от ваших требований.

  • Поместить форму content в пользовательский элемент управления, реализующий интерфейс для выполнения пользовательской логики
  • Вывести классы из DataGridView, реализующего интерфейс для выполнения пользовательской логики
  • Как уже говорилось, используйте конкретный класс с виртуальными методами вместо использования абстрактного класса
  • ....

Вам придется выбрать вариант, который лучше всего подходит для ваших нужд. Не зная области и специфики, в которой задан ваш вопрос, я не думаю, что мы можем дать вам 100% определенный ответ.

4
ответ дан 4 December 2019 в 03:39
поделиться

Ознакомьтесь с этим методом , чтобы узнать, как создать два необходимых атрибута.

Вам понадобится следующий атрибут и класс дескриптора типа (код взят из 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() { }
}

. Это должно работать.

1
ответ дан 4 December 2019 в 03:39
поделиться

У меня та же проблема.
Эта страница может вам помочь, хотя это всего лишь обходной путь: Наследование формы от абстрактного класса (и обеспечение ее работы в конструкторе) .

Я не нашел лучшего решения, но, похоже, нет. Так что действительно Windows Forms Designer заставляет вас адаптировать дизайн вашего класса.

0
ответ дан 4 December 2019 в 03:39
поделиться
Другие вопросы по тегам:

Похожие вопросы: