There are tons of articles around in the web dealing with the implementation of the Model View Controller (MVC) pattern. Nevertheless, I had a hard time finding one usable as a kind of blueprint for a little software project of mine - a Windows Forms application with database access and data table display using the .NET DataGridView. Finally I found Matthew Cochran's article: Introduction to Model View Control (MVC) Pattern using C# which helped me a lot in getting an MVC up and running.
Still, I always thought that it would have been useful for me to have something closer to real life - and involving a .NET DataGridView. This is what I want to provide in this blog, even if it shows work in progress.
Technical Framework
System: WinXP SP3
.NET version: 4.0
IDE: Visual Studio C# 2010 Express
DB: SQL Server Express 2008 Express
The UI
Here is what I wanted: a simple UI which enables the user to edit data stored in a database table. The user should be able to view the current data available in the DB, edit values of existing DB table entries, add lines to the data, delete lines and save the data. In the end I want to have a user interface to maintain a couple of database tables. The individual tables are accessible via a dropdown menu in a main window. Each user request from the main window invokes a form for editing data stored in one DB table:
The window called by the user command looks like this:
The mouse points to what will become the save button.
So far I have implemented only data retreval from the DB, changing data in the UI and saving this data back to the DB. The "delete line" and "add line" features are still missing, but I think the existing functionality is enough to show the principles.
The Model
The model is responsible for any DB interaction and data manipluation. Following Matthew's article I created an interface for the model:
Note: Don't get irritated by the order of the methods - I just like sorting them alphabetically...
As one might guess by the interface name, I want to use this model in the future to handle DB table data independent of the concrete DB table. This is similar to Matthew's IVehicleModel together with the implementation in class Automobile.
The interface is then implemented in an abstract class which serves as a blueprint for the table dependent implementation and which implements the MVC-relevant logic:
public void addObserverView(IDBTableEditorView inTeamTypeView)
{
theTeamTypeView = inTeamTypeView;
}
Code
public void notifyObserverView()
{
theTeamTypeView.updateUserInterface(this);
}
Code
public void deleteLineFromTable()
{
}
Code
public virtual void writeDataToDB(DataTable inDataTable)
{
}
C#
publicvirtual DataTable readDataFromDB()
{
DataTable lt_DataTable = new DataTable();
//Add code for concrete data retreval here in concrete classreturn lt_DataTable;
}
}
Note: those methods that require table-specific logic have the attribute "virtual".
In this specific example I'm dealing with a DB table called "TeamTypes" and which has 3 columns (TeamTypeID (char(3)), TeamTypeDesc (varchar(100)), TeamTypeNumber (bigint)). Thus I have to create a specific table-dependent implementation of my virtual base class called "classTeamTypesModel", in this class I have to override the two "virtual" methods:
Code
class classTeamTypesModel : classDBTableEditorModel
{
public classTeamTypesModel(string teamTypeName):base(teamTypeName)
{
}
TypeScript
publicoverrideDataTablereadDataFromDB()
{
DataTable lt_TeamTypes = newDataTable();
//Read data from DB via connectortry
{
lt_TeamTypes = classSqlServerConnector.Instance.TeamTypeReadAll;
}
catch { }
return lt_TeamTypes;
}
publicoverridevoidwriteDataToDB(DataTable inDataTable)
{
classSqlServerConnector.Instance.TeamTypeUpdateRecords(inDataTable);
}
}
Note: the classSqlServerConnector is not part of the MVC, but hosts all the functionality to read/write data from/to the DB and will not be discussed here.
The Controller
Following Matthew's article I created an interface for the controller as well:
public void updateUserInterface(IDBTableEditorModel inTeamTypeModel)
{
this.dataGridTeamTypes.Update();
}
TypeScript
privatevoidformTeamTypes_Load(object sender, EventArgs e)
{
//When Form is called, the data for Team Types are read from DB
dataGridTeamTypes.DataSource = theTeamTypesController.onView_Load();
dataGridTeamTypes.Columns[0].HeaderText = "Type ID";
dataGridTeamTypes.Columns[1].HeaderText = "Type Description";
dataGridTeamTypes.Columns[2].Visible = false;
//Add a fourth virtual column for a marker flag to mark changed rows
dataGridTeamTypes.Columns.Add("ChangedFlag", "Changed Flag");
dataGridTeamTypes.Columns[3].Visible = false;
}
C#
privatevoidbuttonSave_Click(object sender, EventArgs e)
{
DataTable lt_RowsForUpdate = new DataTable();
DataRow ls_DataRow;
//Build internal table with rows for update
lt_RowsForUpdate.Columns.Add("TeamTypeID");
lt_RowsForUpdate.Columns.Add("TeamTypeDesc");
lt_RowsForUpdate.Columns.Add("TeamTypeNumber");
lt_RowsForUpdate.Columns.Add("Changed");
//Check for Changes and write to DBfor (int i = 0; i < dataGridTeamTypes.Rows.Count; i++)
{
if (dataGridTeamTypes.Rows[i].Cells[3].Value != null &&
dataGridTeamTypes.Rows[i].Cells[3].Value.ToString() == "C")
{
ls_DataRow = lt_RowsForUpdate.NewRow();
ls_DataRow[0] = dataGridTeamTypes.Rows[i].Cells[0].Value;
ls_DataRow[1] = dataGridTeamTypes.Rows[i].Cells[1].Value;
ls_DataRow[2] = dataGridTeamTypes.Rows[i].Cells[2].Value;
lt_RowsForUpdate.Rows.Add(ls_DataRow);
}
}
theTeamTypesController.onButtonSave_Click(lt_RowsForUpdate);
}
TypeScript
privatevoiddataGridTeamTypes_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
//Mark rows which have been changedif (e.RowIndex >= 0)
{
dataGridTeamTypes.Rows[e.RowIndex].Cells[3].Value = "C";
}
}
}
Note: marking the changed rows with a "C" might be a bit clumsy, but I didn't find a better way. Maybe you have a better one - I'd be glad to get to know about it.
Calling the MVC from the Application
The whole MVC cluster is called by the standard invocation of the form from wherever (here from the event menu item XYZ_clicked:
Upendra Pratap ShahiPosted Oct 26, 2015, 10:30 AM
nice explain.
Vinod ThakarePosted Jan 21, 2015, 11:39 PM
Excellent Article!!
Mg KyaingPosted Aug 18, 2014, 11:23 AM
please code share me to [email protected] Thank U.........
Mg KyaingPosted Aug 18, 2014, 11:22 AM
Nice one :) Thank
Luong ThápPosted Jun 16, 2014, 2:57 AM
Help me with Multiple Model
lalita pophalePosted Apr 24, 2013, 6:43 AM
Excellent Article!! Can you please share the complete code of this example.
sushith msPosted Aug 14, 2011, 12:28 AM
please share code above explained to my [email protected]
sushith msPosted Aug 14, 2011, 12:28 AM
please share code above explained to my [email protected]
sushith msPosted Aug 14, 2011, 12:28 AM
please share code above explained to my [email protected]