使用EF和SQL后端使用基本MVP模式Winforms App

时间:2015-11-14 14:43:07

标签: c# winforms oop mvp

我正在编写一个应用程序,在阅读并遵循许多示例后,我实现了一个基本的MVP模式。在简单的维护屏幕上,它工作得很好;但是在更复杂的屏幕上,模式并不是那么好。

这是一个带有接口的短代码块,以及通过LINQ获取一些数据的第一种方法。演示者都与模型分开,每个模型POCO都是通过EF-codefirst生成的。

public interface ILocnMastView
    {
        int LocnMastID { get; set; }
        Int16 LocnSubTypeID { get; set; }

        event EventHandler<EventArgs> FetchLocnMasts;

        //Event to fire a 'fetch' of a row of data
        event EventHandler<EventArgs> RefreshLocnMast;
    }
    public interface ILocnMastData : ILocnMastView
    {
        //Event to fire a record INSERT
        event EventHandler<EventArgs> InsertLocnMast;

        //Event to fire a record UPDATE
        event EventHandler<EventArgs> UpdateLocnMast;
    }

    public class PresenterLocnMast
    {
        #region Member Variables
        private ILocnMastView _viewfetch;                 //The view (form) instance that this presenter interface will use
        private ILocnMastData _viewdata;                  //The view (form) instance that this inherited interface will use
        private LOCNMast _obj = new LOCNMast();             //A single row of data to be returned out of this class
        private List<LOCNMast> _data = null;              //List of supplycodes to be returned out of this class
        private List<LocnMastObject> _dataobject;    //List of contacts joined to persontype table in a specialised class object
        private string _message = string.Empty;
        #endregion Member Variables

        #region Member Properties

        public string Message
        {
            get { return _message; }
            set { _message = value; }
        }
        public LOCNMast Locnmast
        {
            get { return _obj; }
            set { _obj = value; }
        }
        public List<LOCNMast> LocnMasts
        {
            get { return _data; }
            set { _data = value; }
        }
        public List<LocnMastObject> LocnMastObjects
        {
            get { return _dataobject; }
            set { _dataobject = value; }
        }
        #endregion Member Properties

        #region Member Objects
        public class LocnMastObject
        {
            public int ID { get; set; }
            public string combinedtext { get; set; }
            public string Name { get; set; }
            public string Description { get; set; }
            public string LocationType { get; set; }
            public string Warehouse { get; set; }
            public string Category { get; set; }
            public DateTime LastEditedDate { get; set; }
            public string LastEditedBy { get; set; }
            public Boolean Active { get; set; }
        }
        #endregion Member Objects

        #region Init
        public PresenterLocnMast(ILocnMastView viewfetch, ILocnMastData viewdata)
        {
            this._viewfetch = viewfetch;
            this._viewdata = viewdata;
            this.Initialise();
        }

        private void Initialise()
        {
            if (_viewdata != null)
            {
                this._viewdata.UpdateLocnMast += new EventHandler<EventArgs>(UpdateLocnMast);
                this._viewdata.InsertLocnMast += new EventHandler<EventArgs>(InsertLocnMast);
            }
            this._viewfetch.FetchLocnMasts += new EventHandler<EventArgs>(FetchLocnMasts);
            this._viewfetch.RefreshLocnMast += new EventHandler<EventArgs>(RefreshLocnMast);
        }
        #endregion Init

        #region Methods

        /// <summary>
        /// Routine:    FetchLocnMasts
        /// Purpose:    Event to Fetch all details from the database by locnsubtype
        /// Author:     Frustrated Winforms Developer
        /// Date:       13/11/2015
        /// </summary>
        private void FetchLocnMasts(object sender, EventArgs e)
        {
            try
            {
                using (var db = new DevDBContext())

                    var queryforobject = from l in db.LOCNMasts.AsNoTracking()
                                         join t in db.LocnTypes.AsNoTracking() on l.LocationTypeID equals t.ID
                                         join w in db.WHMasts.AsNoTracking() on l.WarehouseID equals w.ID
                                         join c in db.LocnCategoryTypes.AsNoTracking() on l.LocationCategoryTypeID.Value equals c.ID into pp
                                         from LocationCategoryTypeID in pp.DefaultIfEmpty()
                                         orderby l.Name

                                         //Put the query results into the bespoke object
                                         select new LocnMastObject { ID = l.ID, 
                                                                     Name = l.Name, 
                                                                     Description = l.Description, 
                                                                     combinedtext = l.Name + " - " + l.Description,
                                                                     LocationType = t.Description,
                                                                     Warehouse = w.Description,
                                                                     Category = LocationCategoryTypeID.Name,
                                                                     LastEditedBy = l.LastEditedBy, 
                                                                     LastEditedDate = l.LastEditedDate, 
                                                                     Active = l.Active };
                    if (queryforobject.Count() > 0)
                        _dataobject = queryforobject.ToList();
                }
            }
            catch (Exception ex)
            {
                //HandleError
            }
        }

所以,一切都好。 在表单上,​​我必须实现接口,为关键字段设置私有成员变量和属性,创建演示者类的实例并创建事件以匹配接口中定义的事件。

因此,在必须从6个演示者类中提取数据的表单上,代码是最重要的,具有多个实现,每个表的mutli ID属性等等。在复杂的形式上,该方法与传统的OOP方法相比没有任何重大优势。

关于如何解决这个问题的任何想法?我的相关表的另一个类继承了必要的演示者吗?

表单上的代码(注意三个接口实现):

public partial class frmConfigLocation : Telerik.WinControls.UI.RadForm, IWHMastView, ILocnCategoryTypeView, ILocnMastData
#region Member Variables
private Int16 _locationcategorytypeid = -1;
        private Int16 _whmastid = -1;
        private int _locnmastid = -1;
        private Int16 _locnsubtypeid = -1;
        private PresenterWHMast _presenterwhmast;
        private PresenterLocnCategoryType _presenterlocncategorytype;
        private PresenterLocnMast _presenterlocnmast;
        #endregion Member Variables

        #region Member Events
        public event EventHandler<EventArgs> FetchLocnCategoryTypes;
        public event EventHandler<EventArgs> RefreshLocnCategoryType;    

        public event EventHandler<EventArgs> FetchWHMasts;     
        public event EventHandler<EventArgs> RefreshWHMast;

        public event EventHandler<EventArgs> FetchLocnMasts;
        public event EventHandler<EventArgs> RefreshLocnMast;
        public event EventHandler<EventArgs> UpdateLocnMast;
        public event EventHandler<EventArgs> InsertLocnMast;
        #endregion Member Events

public Int16 LocnCategoryTypeID
        {
            get { return _locationcategorytypeid; }
            set { _locationcategorytypeid = LocnCategoryTypeID; }
        }
        public Int16 WHMastID
        {
            get { return _whmastid; }
            set { _whmastid = WHMastID; }
        }
        public int LocnMastID
        {
            get { return _locnmastid; }
            set { _locnmastid = LocnMastID; }
        }
        #endregion Member Properties

        #region FormMethods
        public frmConfigLocation()
        {
            this.FormClosed += new FormClosedEventHandler(frmLocation_FormClosed);
            InitializeComponent();
            _presenterlocnmast = new PresenterLocnMast(this, this);
            _presenterlocncategorytype = new PresenterLocnCategoryType(this, null);
            _presenterwhmast = new PresenterWHMast(this, null);
        }

所以,毕竟,填充radGrid的例程很简单

private void FetchData([Optional] Boolean postsave)
        {
            try
            {
                this.Cursor = Cursors.WaitCursor;
                if (FetchLocnMasts != null)
                {
                    FetchLocnMasts(this, EventArgs.Empty);
                    radGridViewLocnAll.DataSource = _presenterlocnmast.LocnMastObjects;

                    //Hide the ID column of the radgrid
                    GlobalControlMethods.radGridViewColumnVisible(radGridViewLocnAll, 0, false);
                    radGridViewLocnAll.CurrentRow = null;

                }

正如您所看到的,尽管获取数据非常简单,但仍需要很多代码来设置所有内容。我必须遗漏一些东西才能使表格背后的代码少得多,这一点肯定是肯定的?

很抱歉很长的帖子,欢迎所有反馈!

0 个答案:

没有答案