Параметризованные формы
От: Аноним  
Дата: 17.11.10 06:34
Оценка:
Доброго времени суток!

При разработке столкнулись со следующей проблемой:
есть достаточно большое количество бизнес-сущностей, которые хранятся в базе данных.
При необходимости работы с ними — бизнес-объекты загружаются из базы данных.

Все бизнес-объекты (для удобства) реализуют простейший интерфейс:


    public interface IEntity
    {
        /// <summary>
        /// Уникальный номер сущности в базе данных
        /// </summary>
        int ID { get; set; }
        
        /// <summary>
        /// Осуществляет сохранение объекта
        /// </summary>
        void Save();
    }


Этот интерфейс реализуется следующим образом


    public class Customer : IEntity
    {

        public delegate void UpdatedEventHandler(Customer sender, EventArgs e);
        public event UpdatedEventHandler Updated; 

        #region Служебные переменные
        /// <summary>
        /// Уникальный код клиента
        /// </summary>
        public int ID { get; set; }

        /// <summary>
        /// Инн клиента
        /// </summary>
        public string IdentificationNumber { get; set; }

        /// <summary>
        /// Адрес регистрации (прописки) клиента
        /// </summary>
        public Address RegistrationAddress { get; set; }

        /// <summary>
        /// Адрес проживания (фактический) адрес клиента
        /// </summary>
        public Address ResidenceAddress { get; set; }

        /// <summary>
        /// Вид деятельности (клиента)
        /// </summary>
        public ActivityType ActivityType { get; set; }

        /// <summary>
        /// Первый контактный телефон клиента
        /// </summary>
        public string ContactPhone1 { get; set; }

        /// <summary>
        /// Второй контактный телефон клиента
        /// </summary>
        public string ContactPhone2 { get; set; }

        /// <summary>
        /// Электронный адрес клиента
        /// </summary>
        public string EMail { get; set; }
 ...

        #region public void Save()
        /// <summary>
        /// Осуществляет сохранение информации о клиенте в базе данных
        /// </summary>
        public void Save()
        {
            this.daCustomer.Save(this);
            
            if (Updated != null)
                Updated(this, EventArgs.Empty);
        } 
        #endregion
}


Теперь необходимо вытащить объект на форму для пользовательского редактирования.
Алгоритм работы с формой стандартный:

— отобразить данные сущности
— применить настройки безопасности для текущего пользователя
после того, как пользователь внесет изменения выполнить следующий алгоритм:

— провести валидацию данных
— "собрать" объект на основе тех данных, которые внес пользователь
— осуществить сохранение данных

Класс-формы выглядит следующим образом


using System;
using System.Windows.Forms;

using Entities.Management;

namespace Entities.Forms
{
    /// <summary>
    /// Базовая форма для отображения и редактирования объектов
    /// </summary>
    /// <typeparam name="T">Тип объекта для отображения</typeparam>
    public partial class fParent <T>: Form
        where T : IEntity
    {
        /// <summary>
        /// Объект, для которого осуществляется редактирование и просмотр свойств
        /// </summary>
        protected T Item { get; set; }

        /// <summary>
        /// Создание новой формы - справочника
        /// </summary>
        public fParent()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Осуществляет загрузку данных с формы в объект
        /// </summary>
        protected virtual void ComposeData()
        {
        }

        /// <summary>
        /// Осуществляет заполнение элементов формы
        /// </summary>
        protected virtual void FillElements()
        {
        }

        /// <summary>
        /// Осуществляет валидацию данных на форме
        /// </summary>
        /// <param name="message">Сообщение, которое выдается пользователю в случае ошибки</param>
        /// <returns>True, если валидация прошла успешно. False - в противном случае</returns>
        protected virtual bool ValidateData(out string message)
        {
            message = "";
            return true;
        }

        /// <summary>
        /// Осуществляет сохранение данных с формы
        /// </summary>
        protected virtual void SaveData()
        {
            Item.Save();
        }

        /// <summary>
        /// Осуществляет применение настроек безопасности
        /// </summary>
        protected virtual void ApplySecuritySettings()
        {
        }

        /// <summary>
        /// Осуществляет редактирование данных объекта
        /// </summary>
        /// <param name="item">Описание объекта для редактирования</param>
        /// <param name="showModal">Следует ли отображать окно в диалоговом режиме</param>
        /// <returns></returns>
        public DialogResult EditItem(T item, bool showModal)
        {
            this.Item = item;
            this.FillElements();
            this.ApplySecuritySettings();

            if (showModal)
                return this.ShowDialog();
            else
            {
                this.MdiParent = UIManager.MDIForm;
                this.Show();
                return DialogResult.OK;
            }
        }


        #region private void bSave_Click(object sender, EventArgs e)
        private void bSave_Click(object sender, EventArgs e)
        {
            // осуществляет сохранение данных об объекте

            string message;
            bool ok = ValidateData(out message);

            if (!ok)
            {
                MessageBox.Show("Во время верификации данных произошла ошибка:" + Environment.NewLine +
                    Environment.NewLine + message, Settings.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            try
            {
                this.ComposeData();
                this.SaveData();
            }
            catch (Exception ex)
            {
                MessageBox.Show("Во время сохранения данных произошла ошибка:" + Environment.NewLine +
                    Environment.NewLine + ex.Message, Settings.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
                return;
            }

            this.DialogResult = DialogResult.OK;
            this.Close();
        } 
        #endregion

        #region private void bCancel_Click(object sender, EventArgs e)
        private void bCancel_Click(object sender, EventArgs e)
        {
            this.DialogResult = DialogResult.Cancel;
            this.Close();
        } 
        #endregion

    }
}


Дизайнер форм прекрасно понимает и работает с этой формой.
Теперь, когда дело доходит до отдельной формы, которая представляет отдельный бизнес-объект. Имеем следующее:


    /// <summary>
    /// Отображение формы для редактирования отдельной доверенности
    /// </summary>
    public partial class fCustomer : fParent <Customer>
    {

        #region public fCustomer()
        /// <summary>
        /// Создание новой формы для отдельного клиента
        /// </summary>
        public fCustomer()
            : base()
        {
            InitializeComponent();
        } 
        #endregion


        #region protected override void FillElements()
        /// <summary>
        /// Осуществляет заполнение данных
        /// </summary>
        protected override void FillElements()
        {
            string accountName = Item.Account.AccountName;
            this.tAccountName.Text = (accountName == null) ? "" : accountName.Trim();

            this.tAttorneyNo.Text = Item.AttorneyNo;
...
          

        } 
        #endregion

        #region protected override void ComposeData()
        /// <summary>
        /// Осуществляет заполнение объекта на основе данных формы
        /// </summary>
        protected override void ComposeData()
        {
            // валидация уже прошла, можем заполнять данные
            Item.AttorneyNo = tAttorneyNo.Text.Trim();
            Item.Description = tDescription.Text.Trim();
...
        } 
        #endregion

        #region protected override bool ValidateData(out string message)
        /// <summary>
        /// Осуществляет проверку введенных данных пользователем на форме.
        /// </summary>
        /// <param name="message">Сообщение, которое отображается в случае ошибок заполнения</param>
        /// <returns>True, если проверка пройдена успешно, False, если есть замечания</returns>
        protected override bool ValidateData(out string message)
        {
            // проверяем, чтобы были заданы необходимые поля

            bool ok = true;
            message = "";

            if (!UIValidator.ValidateEmptyString(tAttorneyNo, lAttorneyNo, false))
            {
                ok = false;
                message += "Необходимо указать номер доверенности" + Environment.NewLine;
            }

            if (!UIValidator.ValidateEmptyString(tDescription, lDescription, false))
            {
                ok = false;
                message += "Необходимо указать полномочия доверенного лица" + Environment.NewLine;
            }
...

            return ok;
        }
        #endregion

    }


И здесь начинаются проблемы.
Дизайнер не загружается, и пишет следующую проблему

The designer could not be shown for this file because none of the classes within it can be designed. The designer inspected the following classes in the file: fCustomer --- The base class 'Entities.Forms.fParent' could not be loaded. Ensure the assembly has been referenced and that all projects have been built.

Хотя компиляция проекта и его работа работают корректно.

Буду благодарен любым советам, комментариям и ссылкам
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.