zoukankan      html  css  js  c++  java
  • MVC in WinForm

    最近在利用C# WinForm进行项目编码的时候发现,如果不恰当的使用Partial关键字或者是User Control,会导致逻辑代码和UI代码耦合度过高,往往会造成一个页面下面会有将近2000行代码……这,当然不是我所要看到的,我急需要一种模式能够将代码分散,并且最好做到逻辑和UI的分离。找来找去,发现MVC模式最好用,就用这个吧。

    当然,拿来用,肯定得明白它的实现方式,对于MVC这种模式,我也已经不是第一次接触了,就来简单的说点吧。

    MVC基本概念

    MVC,指的是Model View Controller,其核心是利用Controller来策动Model和View,简而言之,Controller就是生成Model和View的。请看下面的图示:

            

    这里我就来说下创建步骤:

    首先,Controller中需要有待操作的View和与之对应的Model,然后主要进行逻辑代码的编写。

    其次,View中需要有之对应的Controller的实例,这样才能方便调用Controller中的逻辑方法。

    最后就是启动的时候,最好是Controller First,而不是View First.

    需要注意的是,在MVC中,我们倾向于在Model类中使用INtofifyPropertyChanged接口;我们倾向于利用DataBindings来绑定数据。

    MVC具体使用实例

    下面就以一个刚刚编写的字模制作小软件来说明:

    在Controller中,我们需要指明需要操作的View和Model:

    View Code
     public WordMakerController(MainFrm mainFrm)
            {
                this.mainFrm = mainFrm;
                this.mainFrm.MController = this;
    
                //调用构造器实现数据缓存
                wordReponsitory = new WordReponsitory();
            }
    
            //我要操作的View
            public MainFrm mainFrm;
    
            //我要操作的Model
            public object datasource = DataCache.model;

    指明之后,剩下的就是操作逻辑了:

    View Code
    //添加操作,主要是将标记写入
            public void Add(Button thisBtn, string flag)
            {
    
                thisBtn.Text = flag;
                string content = string.Empty;
                if (flag.Contains("/"))
                    content = @"strArray[" + thisBtn.Tag + "]=" + "\"/\";";
                if (flag.Contains("\\"))
                    content = @"strArray[" + thisBtn.Tag + "]=" + "@" + "\"\\\";";
    
                if (!list.Contains(content))
                {
                    list.Add(content);
                    SortAndIntegration();
                }
            }
    
            //删除操作,删除已有的标记。
            public void Remove(Button thisBtn, string flag)
            {
                string content = string.Empty;
                if (flag.Contains("/"))
                    content = @"strArray[" + thisBtn.Tag + "]=" + "\"/\";";
                if (flag.Contains("\\"))
                    content = @"strArray[" + thisBtn.Tag + "]=" + "@" + "\"\\\";";
    
                thisBtn.Text = string.Empty;
                if (list.Contains(content))
                {
                    list.Remove(content);
                    SortAndIntegration();
                }
            }
    
            //对List数组进行排序
            private void SortAndIntegration()
            {
                list.Sort(1, list.Count - 1, null);
                DataCache.model.MyArray = string.Join(newLine, list.ToArray());
            }
    
            //本字模软件的核心就是此类,将输入的字母拷贝到一个大数组,然后循环行列打印出来。
            private void Punch(int count, string[,] strDaemon, string[,] strPartly)
            {
                for (int row = 0; row < 7; row++)
                {
                    for (int column = 0; column < 16; column++)
                    {
                        strDaemon[row, count * 16 + column] = strPartly[row, column];
                    }
                }
            }
    
            //解析输入的单词
            public string[,] make(string text)
            {
                //string text = txtWord.Text;
    
                int len = text.Length;
    
                string[,] str = new string[7, len * 16];
                int count = -1;
                foreach (char c in text)
                {
                    switch (c)
                    {
                        case 'A':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayA);
                            break;
    
                        case 'B':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayB);
                            break;
    
                        case 'C':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayC);
                            break;
    
                        case 'D':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayD);
                            break;
    
                        case 'E':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayE);
                            break;
    
                        case 'F':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayF);
                            break;
    
                        case 'G':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayG);
                            break;
    
                        case 'H':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayH);
                            break;
    
                        case 'I':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayI);
                            break;
    
                        case 'J':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayJ);
                            break;
    
                        case 'K':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayK);
                            break;
    
                        case 'L':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayL);
                            break;
    
                        case 'T':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayT);
                            break;
    
                        case 'O':
                            count++;
                            Punch(count, str, WordReponsitory.strArrayO);
                            break;
                        default: break;
    
    
                    }
                }
                return str;
            }

    在Model中,倾向于利用INotifyPropertyChanged接口实现属性改变后通知到绑定

    View Code
    public class NotifiedModel:INotifyPropertyChanged
        {
    
            private string myArray;
            public string MyArray
            {
                get { return myArray; }
                set { myArray = value; NotifyPropertyChanged("MyArray"); }
            }
    
            public event PropertyChangedEventHandler PropertyChanged;
    
            public void NotifyPropertyChanged(string info)
            {
                PropertyChangedEventHandler property_changed = PropertyChanged;
                if (property_changed != null)
                {
                    property_changed(this,new PropertyChangedEventArgs(info));
                }
            }
        }

    在View中,需要实例化Controller,然后调用Controller代码逻辑即可,所有的操作基本都和UI交互有关,大大降低了代码的耦合度:

    View Code
     public MainFrm()
            {
                InitializeComponent();
            }
    
            //这里需要保存Controller的实例,以便方便调用逻辑方法 
            private WordMakerController mController;
            public WordMakerController MController
            {
                get { return mController; }
                set { mController = value; }
            }
            
            private void MainFrm_Load(object sender, EventArgs e)
            {
                //这里是进行数据绑定
                string header = "string[,] strArray = new string[7, 16];";
                mController.list.Add(header);
                richTextBox1.DataBindings.Add("Text", mController.datasource, "MyArray");
    
                LoadWordModel();
            }
    
            private void LoadWordModel()
            {
                Button[,] btn = new Button[7, 16];
    
                for (int m = 0; m < 7; m++)
                {
                    for (int n = 0; n < 16; n++)
                    {
                        btn[m, n] = new Button();
                        Button t = btn[m, n];
    
                        t.Size = new Size(20, 20);
                        t.FlatStyle = FlatStyle.Popup;
                        t.Top = m * 20;
                        t.Left = n * 20;
                        t.Tag = m + "," + n;
    
                        t.MouseDown += (senderE, eE) =>
                        {
                            ClickAndFlag(senderE, eE);
                        };
    
                        panel1.Controls.Add(t);
                    }
                }
            }
    
            //这里通过点击鼠标,然后将标记加入到数组里。主要进行字模制作
            private void ClickAndFlag(object senderE, object eE)
            {
                Button thisBtn = ((Button)(senderE));
                if (eE is MouseEventArgs)
                {
                    MouseEventArgs e = eE as MouseEventArgs;
                    if (e.Button == MouseButtons.Left)
                    {
                        if (String.IsNullOrEmpty(thisBtn.Text))
                            //Add(thisBtn, "\"/\";");
                            mController.Add(thisBtn, "/;");
                        else
                            mController.Remove(thisBtn, "/;");
                    }
                    if (e.Button == MouseButtons.Right)
                    {
                        if (String.IsNullOrEmpty(thisBtn.Text))
                            //Add(thisBtn, "@"+"\"\\\";");
                            mController.Add(thisBtn, "\\;");
                        else
                            mController.Remove(thisBtn, "\\;");
                    }
                }
            }
    
            //生成字模
            private void button1_Click(object sender, EventArgs e)
            {
                string[,] str = mController.make(txtWord.Text);
    
                string text = txtWord.Text;
    
                int len = text.Length;
    
                for (int row = 0; row < 7; row++)
                {
                    int count = 0;
                    for (int colum = 0; colum < len * 16; colum++)
                    {
                        count++;
                        //if (string.IsNullOrEmpty(strArrayA[row, colum])) strArrayA[row, colum] = " ";
                        if (str[row, colum] == null) str[row, colum] = " ";
    
                        rText.AppendText(str[row, colum]);
    
                        if (count == len * 16)
                        {
                            rText.AppendText("\r\n");
                        }
                    }
                }
            }

    最后说明下启动,由于是Controller是策动者,所以应当是ControllerFirst:

    View Code
                //Controller实例化先
                WordMakerController wordMakerController = new WordMakerController(new MainFrm());
                //启动由Controller生成的窗体
                Application.Run(wordMakerController.mainFrm);

     实例运行的结果

    然后把生成好的字符拷贝到VisualStudio中, 在VisualStudio中的显示如下:

    源码下载

    最后么当然是提供源码下载

  • 相关阅读:
    HTTP——学习笔记(3)
    HTTP——状态码
    HTTP——学习笔记(2)
    HTTP——学习笔记(1)
    Sqlserver 存储过程
    Sqlserver 函数(例子)
    Sqlserver 函数
    sqlserver字段类型
    redis入门笔记(2)
    redis入门笔记(1)
  • 原文地址:https://www.cnblogs.com/scy251147/p/2775077.html
Copyright © 2011-2022 走看看