登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

学无止境

一点积累,与大家分享

 
 
 

日志

 
 

Model View Controller (MVC) Using C#, Delegates and Events in .NET  

2010-06-01 11:03:16|  分类: C#技术 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

Model View Controller

The actual pattern employed in this example, is Model View Controller (MVC). The Windows Forms component will act as the View. There's a book class which represents the Model. The actual Controller logic isn't separated from the View/Model because of my primary design goals. I will publish an extensive MVC-system in the near future which will be reusable for all kind of .NET applications.

Delegates

A delegate is a type-safe method reference. With usage of delegates, programs can dynamically call methods at runtime. In contrast to our MVC pattern delegates provide a solid infrastructure to implant the publish-subscribe notification pattern. For those who have experience with Java, I'm referring to the Observer/Observable registration functionality witch the JDK 1.3 provides for exploiting the MVC pattern in the Java environment.

Events

An event is common in modern programming languages. The basic usage of events is indicating certain user-defined occurrences inside your program. Events are used to notify certain listeners during the program lifetime. A very good example is button clicks or other dynamic actions in your programs. Events are again powered by the publish/subscriber pattern.

The model

While coding this basic example in order to explore MVC pattern I thought of books obviously. Below displayed is a basic book class implementation. This Book class contains a private member called bookPrice. The basic functionality I want to provide for all object who wish to instantiate my book class is an actual book price, in the case that the price changes, my views will update their views in order to display the actual book price. The idea is simple so lets move on? see the comments in the code.

Model View Controller (MVC) Using C, Delegates and Events in .NET - 每天积累一点 - 学无止境 Collapse
using System;
namespace MVC
{
public class Book
{
// declare a delegate for the bookpricechanged event

public delegate void BookPriceChangedHandler(objectsender,
BookPriceChangedEventArgs e);

// declare the bookpricechanged event using the bookpricechangeddelegate

public event BookPriceChangedHandler BookPriceChanged;

// instance variable for book price

object _bookPrice;

// property for book price

public object BookPrice
{
set
{
// set the instance variable

_bookPrice=value;

// the price changed so fire the event!

OnBookPriceChanged();
}
}

// method to fire price canged event delegate with proper name

// this is the method our observers should be implenting!

protected void OnBookPriceChanged()
{
BookPriceChanged(this, new BookPriceChangedEventArgs(_bookPrice));
}
}
}

So what happened here; we'd structured the basic layout for the book class. Notice the declared delegate and event BookPriceChangedHandler and BookPriceChanged. The delegate encapsulates the BookPriceChanged method. Later we'll see why, but for know its enough to know that the BookPriceChanged method will be implemented in the object that wishes to observe this book class. As you can see, the method gets called with the BookPriceChangedEventArgs. This argument object contains the public properties the book object encapsulates. This is just the standard way for transporting multiple parameters towards methods. Kind of basic programming, so this should be self explanatory. Lets take a brief look at the BookPriceChangedEventArgs class.

Model View Controller (MVC) Using C, Delegates and Events in .NET - 每天积累一点 - 学无止境 Collapse
namespace MVC
{
// specialized event class for the bookpricechanged event

public class BookPriceChangedEventArgs : EventArgs
{
// instance variable to store the book price

private object _bookPrice;

// constructor that sets book price

public BookPriceChangedEventArgs(objectbookPrice)
{
_bookPrice=bookPrice;
}

// public property for the book price

public object BookPrice
{
get
{
return _bookPrice;
}
}
}
}

Maybe you noticed that I used the object (like in Java the "any") instead of string declaration for my price value. The main reason for this is that while creating this model I didn't know what kind of GUI representation I wished to use to show my book price value. In case you wish to add more members to the Book class, for instance a name, author, you should extend this EventArgs class. I would consider giving the class a more abstract name like BookChanged.

The view

Now our model is functional so let's move on to the View. Below is a listing of the view object BookView which subscribes to the book model using a delegate. This way the observer gets notified when the price change events is thrown in the model (the observable). You could pass the private book object through reference to multiple views (think of those smart Adobe Photoshop panels, which are views on the underlying model). In this demo I created a simple two-view system making use of a textbox and a basic label to visualize the book model.

Model View Controller (MVC) Using C, Delegates and Events in .NET - 每天积累一点 - 学无止境 Collapse
using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;

namespace MVC
{
public class BookView : System.Windows.Forms.Form
{
private System.ComponentModel.Container components = null;

// Declare our delagate and book object

private Book.BookPriceChangedHandler bookDelegate;
private Book book;

private System.Windows.Forms.Button button1;
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.GroupBox groupBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.GroupBox groupBox2;
private System.Windows.Forms.Label label1;

public BookView()
{
InitializeComponent();

//create new book instance

book=new Book();

// create a new delegate, instance and bind it

// to the observer's bookpricechanged method

bookDelegate = new Book.BookPriceChangedHandler(this.BookPriceChanged);
//add the delegate to the event

book.BookPriceChanged += bookDelegate;
}

protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}

#region Windows Form Designer generated code
private void InitializeComponent()
{
this.button1 = new System.Windows.Forms.Button();
this.textBox1 = new System.Windows.Forms.TextBox();
this.groupBox1 = new System.Windows.Forms.GroupBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.groupBox2 = new System.Windows.Forms.GroupBox();
this.label1 = new System.Windows.Forms.Label();
this.groupBox1.SuspendLayout();
this.groupBox2.SuspendLayout();
this.SuspendLayout();
//

// button1

//

this.button1.Location = new System.Drawing.Point(120, 16);
this.button1.Name = "button1";
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.Click += new System.EventHandler(this.button1_Click);
//

// textBox1

//

this.textBox1.Location = new System.Drawing.Point(8, 16);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 1;
this.textBox1.Text = "";
//

// groupBox1

//

this.groupBox1.Controls.AddRange(new System.Windows.Forms.Control[] {
this.textBox2});
this.groupBox1.Location = new System.Drawing.Point(8, 104);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(120, 64);
this.groupBox1.TabIndex = 2;
this.groupBox1.TabStop = false;
this.groupBox1.Text = "View 1";
//

// textBox2

//

this.textBox2.Location = new System.Drawing.Point(8, 32);
this.textBox2.Name = "textBox2";
this.textBox2.TabIndex = 0;
this.textBox2.Text = "";
//

// groupBox2

//

this.groupBox2.Controls.AddRange(new System.Windows.Forms.Control[] {
this.label1});
this.groupBox2.Location = new System.Drawing.Point(8, 176);
this.groupBox2.Name = "groupBox2";
this.groupBox2.Size = new System.Drawing.Size(120, 64);
this.groupBox2.TabIndex = 3;
this.groupBox2.TabStop = false;
this.groupBox2.Text = "View 2";
//

// label1

//

this.label1.Location = new System.Drawing.Point(8, 32);
this.label1.Name = "label1";
this.label1.TabIndex = 0;
//

// BookView

//

this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(292, 266);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.groupBox2,
this.groupBox1,
this.textBox1,
this.button1});
this.Name = "BookView";
this.Text = "BookView";
this.groupBox1.ResumeLayout(false);
this.groupBox2.ResumeLayout(false);
this.ResumeLayout(false);

}
#endregion

[STAThread]
static void Main()
{
Application.Run(new BookView());
}

public void BookPriceChanged(object sender, MVC.BookPriceChangedEventArgs e)
{
// update bookprice views

object bookPrice;
bookPrice = e.BookPrice;
this.textBox2.Text = bookPrice.ToString();
this.label1.Text = bookPrice.ToString();
}

private void button1_Click(object sender, System.EventArgs e)
{
// change book price

book.BookPrice = this.textBox1.Text;
}
}
}

As soon you make changes to the book price, the BookPriceChanged will be triggered in the model. Because the view is registered to the OnBookPriceChanged method, the BookPricechanged will be invoked from the model. The View (observer) implements the BookPriceChanged method so the views get updated according to the rules as specified in the view upon the book model. Confused? Then start toying with this code because you now know the basics concerning a simple MVC! The book class code is reusable for whatever functionality you wish to provide to the outside world from out your model. Have fun!


from:http://www.codeproject.com/KB/cs/model_view_controller.aspx

  评论这张
 
阅读(957)| 评论(0)

历史上的今天

在LOFTER的更多文章

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018