MVC in WinForm

來源:互聯網
上載者:User

標籤:

最近在利用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:

public WordMakerController(MainFrm mainFrm)
{
this.mainFrm = mainFrm;
this.mainFrm.MController = this;

//調用構造器實現資料緩衝
wordReponsitory = new WordReponsitory();
}

//我要操作的View
public MainFrm mainFrm;

//我要操作的Model
public object datasource = DataCache.model;

指明之後,剩下的就是操作邏輯了:

//添加操作,主要是將標記寫入
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介面實現屬性改變後通知到綁定

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互動有關,大大降低了代碼的耦合度:

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:

 //Controller執行個體化先            WordMakerController wordMakerController = new WordMakerController(new MainFrm());            //啟動由Controller產生的表單            Application.Run(wordMakerController.mainFrm);

 執行個體啟動並執行結果

然後把產生好的字元拷貝到VisualStudio中, 在VisualStudio中的顯示如下:

源碼下載

最後麼當然是提供源碼下載了

MVC in WinForm

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.