简体   繁体   English

WinForms 中的 3 层表示层组织

[英]3 tier presentation layer organisation in WinForms

Am start to building big WinForms application which will contain about 50 forms and will interact with MySQL database.我开始构建大型 WinForms 应用程序,该应用程序将包含大约 50 个表单并将与 MySQL 数据库交互。

Am using 3 tier arhitecture and also use Dapper library.我正在使用 3 层架构并使用Dapper库。

I start with creating simple Data and Business logik layers with Partners entity.我首先使用Partners实体创建简单的数据和业务逻辑层。

Using 3 tier is good organized and simple for maintenance.使用 3 层结构良好且易于维护。

Data数据

  public IList<Partner> GetPartnerList()
    {
        using (Conn)
        {
            string query = @"SELECT p.id, p.naziv, p.pib, p.maticni_br, p.tipId, p.telefon, p.created, p.updated, p.email, p.status, pt.naziv
                    FROM partner p
                    INNER JOIN partner_tip pt ON p.tipId = pt.id ORDER BY p.id DESC";

            var partners =  Conn.Query<Partner, Partner_Tip, Partner>(query, (partnerObj, partner_tipObj) => {
                partnerObj.Tip = partner_tipObj;
                return partnerObj;
            }, splitOn: "naziv");

            return partners.ToList();
        }
    }

Business商业

public IList<Partner> GetPartnerList()
        {
            var partners = partnerDAL.GetPartnerList();
            return partners;
        }

This two layers are so simple and readable and eazy for maintenance.这两层非常简单易读且易于维护。

Problem问题

Problem start when i start to organize Presentation Layer becouse in Form are to much methods, filtrs, dialogs and etc.etc.当我开始组织Presentation Layer时,问题就开始了,因为在表单中有很多方法、过滤器、对话框等等。 Am losed when i need to change somthing in presetation.当我需要更改预设中的某些内容时,我迷路了。

On this layers lets say Partner i create presentation for that like this在这一层上,可以说Partner我为它创建了这样的演示文稿

MyApp.Presentation.Ui.Partners.Common -> here i put form for Display partners and form for insert MyApp.Presentation.Ui.Partners.Reusable -> here i put user controls for partners MyApp.Presentation.Ui.Partners.Common -> 在这里我放置了显示合作伙伴的表单和插入MyApp.Presentation.Ui.Partners.Reusable -> 我在这里放置了合作伙伴的用户控件

In Display form i have datagridview and tons of textboxes for filtering that data in grid.在显示表单中,我有datagridview和大量textboxes用于过textboxes格中的数据。 Also inside are tons of events .里面还有大量的events

I need see how to good organize form for eazy maintance in feature.我需要看看如何很好地组织表单以方便维护功能。 How big project organize this.多大的项目组织这个。 My form are loosable in code.我的表单在代码中很容易丢失。

Any link or solution how to make this better.任何链接或解决方案如何使这更好。

Here is my code of the Form:这是我的表格代码:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using IBLL;
using BLL;
using Model;

namespace Presentation
{
    public partial class Form1 : Form
    {
        BindingSource bindingSource;
        IPartnerBLL partner;
        IPartnerTopBLL partnerTip;

        BindingList<Partner> bindingList;

        // constructor
        public Form1()
        {
            InitializeComponent();

            partner = new PartnerBLL();
            bindingSource = new BindingSource();
            partnerTip = new Partner_TipBLL();

            comboBox1.ValueMember = "id";
            comboBox1.DisplayMember = "naziv";
            comboBox1.DataSource = partnerTip.GetPartnerTipList();
            comboBox1.SelectedIndex = -1;

           dataGridView1.AutoGenerateColumns = false;



            DataGridViewColumn colName = new DataGridViewTextBoxColumn();
            colName.DataPropertyName = "naziv";
            colName.HeaderText = "Naziv";
            colName.Width = 400;
            dataGridView1.Columns.Add(colName);

            DataGridViewColumn colPib = new DataGridViewTextBoxColumn();
            colPib.DataPropertyName = "pib";
            colPib.HeaderText = "PIB";
            colPib.Width = 200;
            dataGridView1.Columns.Add(colPib);


            DataGridViewColumn colMaticni = new DataGridViewTextBoxColumn();
            colMaticni.DataPropertyName = "maticni_br";
            colMaticni.HeaderText = "Maticni br";
            colMaticni.Width = 200;
            dataGridView1.Columns.Add(colMaticni);

            DataGridViewColumn colTip = new DataGridViewTextBoxColumn();
            colTip.DataPropertyName = "tip";
            colTip.HeaderText = "Tip";
            dataGridView1.Columns.Add(colTip);

            DataGridViewColumn colTelefon = new DataGridViewTextBoxColumn();
            colTelefon.DataPropertyName = "telefon";
            colTelefon.HeaderText = "Telefon";
            dataGridView1.Columns.Add(colTelefon);

            DataGridViewColumn colEmail = new DataGridViewTextBoxColumn();
            colEmail.DataPropertyName = "email";
            colEmail.HeaderText = "E-mail";
            dataGridView1.Columns.Add(colEmail);

            DataGridViewCheckBoxColumn colStatus = new DataGridViewCheckBoxColumn();
            colStatus.DataPropertyName = "status";
            colStatus.HeaderText = "Status";

            dataGridView1.Columns.Add(colStatus);

            DataGridViewColumn colCreated = new DataGridViewTextBoxColumn();
            colCreated.DataPropertyName = "created";
            colCreated.HeaderText = "Kreiran";
            dataGridView1.Columns.Add(colCreated);

            DataGridViewColumn colUpdated = new DataGridViewTextBoxColumn();
            colUpdated.DataPropertyName = "updated";
            colUpdated.HeaderText = "Izmenjen";
            dataGridView1.Columns.Add(colUpdated);

            DataGridViewColumn colID = new DataGridViewTextBoxColumn();
            colID.DataPropertyName = "id";
            colID.HeaderText = "ID";
            dataGridView1.Columns.Add(colID);

          this.dataGridView1.Columns[0].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[1].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[2].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[3].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[4].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[5].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[6].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[7].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[8].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
          this.dataGridView1.Columns[9].AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;


            //GetData();

        }

        // Get grid data
        public void GetData()
        {
            dataGridView1.AutoGenerateColumns = false;

            BindingList<Partner> bl = new BindingList<Partner>(partner.GetPartnerList());


            dataGridView1.DataSource = bl;



        }

        // show update form
        private void ShowUpdateForm()
        {

            if (dataGridView1.SelectedRows.Count > 0)
            {
                int id = (int)dataGridView1.CurrentRow.Cells[9].Value;

                Partner partnerObj = partner.GetPartner(id.ToString());

                PartnerInsert form = new PartnerInsert(partnerObj, this);
                form.ShowDialog();
            }
        }

        // Show Delite confirmation
        public void ShowDeliteConfirmation()
        {

            if (dataGridView1.SelectedRows.Count > 0)
            {

                int id = (int)dataGridView1.CurrentRow.Cells[9].Value;

                DialogResult confirmation = MessageBox.Show("Da li zelite da obrisemo izabranog partnera?", "Brisanje", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

                if (confirmation == DialogResult.Yes)
                {
                    partner.Delete(id.ToString());
                    MessageBox.Show("Parner je obrisan");

                    GetData();
                }
            }
        }

        // show insert form
        private void button1_Click(object sender, EventArgs e)
        {
            PartnerInsert partnerInsert = new PartnerInsert(this);
            partnerInsert.ShowDialog();
        }

        // FILTER
        private BindingList<Partner> GetFilter()
        {
            dataGridView1.AutoGenerateColumns = false;
            BindingList<Partner> bindingListFilter = null;

            string id = filterIDTextBox1.Text.TrimStart();
            string naziv = filterNazivTextBox.Text.TrimStart();
            string pib = fiterPIBTextbox.Text.TrimStart();
            string maticni_br = filterMaticniBrTextBox.Text.TrimStart();
            string telefon = filterTelefonTextBox.Text.TrimStart();
            string email = filterEmailTextBox.Text.TrimStart();
            string tip = comboBox1.SelectedText;
            int status = statusCheckBox.Checked == true ? 1 : 0;

            // id filter
            if (!string.IsNullOrEmpty(id) && !string.IsNullOrWhiteSpace(id))
            {
               bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => x.id.ToString().StartsWith(id)).ToList());
            }
            // name filter
            else if (!string.IsNullOrEmpty(naziv) && !string.IsNullOrWhiteSpace(naziv))
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => !string.IsNullOrEmpty(x.naziv) && x.naziv.StartsWith(naziv)).ToList());     
            }
            // pib filter
            else if (!string.IsNullOrEmpty(pib) && !string.IsNullOrWhiteSpace(pib))
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => !string.IsNullOrEmpty(x.pib) && x.pib.StartsWith(pib)).ToList());
            }
            // Maticni filter
            else if (!string.IsNullOrEmpty(maticni_br) && !string.IsNullOrWhiteSpace(maticni_br))
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => !string.IsNullOrEmpty(x.maticni_br) && x.maticni_br.StartsWith(maticni_br)).ToList());
            }
            // Telefon filter
            else if (!string.IsNullOrEmpty(telefon) && !string.IsNullOrWhiteSpace(telefon))
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => !string.IsNullOrEmpty(x.telefon) && x.telefon.StartsWith(telefon)).ToList());
            }
            // Email filter
            else if (!string.IsNullOrEmpty(email) && !string.IsNullOrWhiteSpace(email))
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => !string.IsNullOrEmpty(x.email) && x.email.StartsWith(email)).ToList());
            }
            // Tip filter
            else if (comboBox1.SelectedIndex > -1)
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => x.tipId.ToString().StartsWith(comboBox1.SelectedValue.ToString())).ToList());   
            }

            // status filter
            else if (statusCheckBox.Checked)
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => x.status == 1).ToList());
            }
            else if (statusCheckBox.Checked == false)
            {
                bindingListFilter = new BindingList<Partner>(partner.GetPartnerList().Where(x => x.status == 0).ToList());
            }
            else
            {
               bindingListFilter = new BindingList<Partner>(partner.GetPartnerList());
            }

            return bindingListFilter;
        }


        // filter
        private void filterBtn_Click(object sender, EventArgs e)
        {

            dataGridView1.DataSource = GetFilter();

        }

        // delete
        private void deleteBtn_Click(object sender, EventArgs e)
        {
            ShowDeliteConfirmation();
        }

        // update
        private void editButton_Click(object sender, EventArgs e)
        {
            ShowUpdateForm();
        }

        // Show context menu
        private void dataGridView1_MouseClick(object sender, MouseEventArgs e)
        {
            if (e.Button == MouseButtons.Right)
            {
                ContextMenu m = new ContextMenu();

                MenuItem newItem = new MenuItem("NEW");
                MenuItem updateItem = new MenuItem("EDIT");
                MenuItem deleteItem = new MenuItem("DELETE");

                // events
                newItem.Click += new EventHandler(this.newItem_Click);
                updateItem.Click += new EventHandler(this.updateItem_Click);
                deleteItem.Click += new EventHandler(this.deliteItem_Click);

                m.MenuItems.Add(newItem);
                m.MenuItems.Add(updateItem);
                m.MenuItems.Add(deleteItem);

                int currentMouseOverRow = dataGridView1.HitTest(e.X, e.Y).RowIndex;


                m.Show(dataGridView1, new Point(e.X, e.Y));

            }
        }
        private void newItem_Click(object sender, System.EventArgs e)
        {
            PartnerInsert form = new PartnerInsert(this);
            form.ShowDialog();
        }

        private void updateItem_Click(object sender, System.EventArgs e)
        {
            ShowUpdateForm();
        }


        private void deliteItem_Click(object sender, System.EventArgs e)
        {
            ShowDeliteConfirmation();
        }

        // Test formating
        private void dataGridView1_CellFormatting(object sender, DataGridViewCellFormattingEventArgs e)
        {
            if(e.Value != null)
            {
               // e.Value = e.Value.ToString().ToLower();
                //e.FormattingApplied = true;
            }
        }

        private void filterNazivTextBox_TextChanged(object sender, EventArgs e)
        {
           // dataGridView1.DataSource = GetFilter();

        }

        private void filterIDTextBox1_TextChanged(object sender, EventArgs e)
        {

           // dataGridView1.DataSource = GetFilter();

        }



        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void dataGridView1_RowPostPaint(object sender, DataGridViewRowPostPaintEventArgs e)
        {
            var grid = sender as DataGridView;
            var rowIdx = (e.RowIndex + 1).ToString();

            var centerFormat = new StringFormat()
            {
                // right alignment might actually make more sense for numbers
                Alignment = StringAlignment.Center,
                LineAlignment = StringAlignment.Center
            };

            var headerBounds = new Rectangle(e.RowBounds.Left, e.RowBounds.Top, grid.RowHeadersWidth, e.RowBounds.Height);
            e.Graphics.DrawString(rowIdx, this.Font, SystemBrushes.ControlText, headerBounds, centerFormat);

        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void resertFilterBtn_Click(object sender, EventArgs e)
        {
            dataGridView1.DataSource = null;
        }

        // Id enter event
        private void filterIDTextBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if(e.KeyChar == (char) Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

        private void filterNazivTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

        private void fiterPIBTextbox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

        private void filterMaticniBrTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

        private void filterTelefonTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

        private void filterEmailTextBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            //dataGridView1.DataSource = GetFilter();
        }

        private void comboBox1_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (e.KeyChar == (char)Keys.Enter)
            {
                dataGridView1.DataSource = GetFilter();
            }
        }

    }
}

You can benefit from separating your view logic (it is possible in WinForms) by implementing the Model View Presenter pattern.通过实现 Model View Presenter 模式,您可以从分离视图逻辑(在 WinForms 中是可能的)中受益。

With Model View Presenter, you make each of the UI components (in WinForms it will be forms and user controls) implement a view interface.使用 Model View Presenter,您可以使每个 UI 组件(在 WinForms 中将是窗体和用户控件)实现一个视图界面。

A view interface should contain properties that allow the content and state of the controls in the view to be set and retrieved.视图接口应包含允许设置和检索视图中控件的内容和状态的属性。 It can also include events to report back user interactions such as clicking a button etc.它还可以包括报告用户交互的事件,例如单击按钮等。

example view interface:示例视图界面:

interface INewCustomer 
{
   string CustomerName { get; set; }
   int CustomerId { get; set; }
   event EventHandler SaveClicked;
}

sample project on GitHub. GitHub 上的示例项目。

Passive view Model-View-Presenter in Windows Forms . Windows 窗体中的被动视图 Model-View-Presenter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM