简体   繁体   中英

Using DataGridView in Model-View-Presenter

Situation
I am designing a Windows Forms-application using the Model-View-Presenter structure. This means that every Form has a presenter-class behind it, processing user input. Beside this, I am using a repository structure, meaning that I wish to put all my SQL queries in separate class(es).
For one of my forms, I wish to use a DataGridView to show some data from a database.

What I want
Once a user presses a certain button, I wish to load data from the database in the DataGridView. In other words, I wish to bind my DataGridView1.DataSource to a BindingSource which gets data from the database through an SQL-query.
However, since my DataGridView is private, I cannot access its datasource from my presenter- or repository-class.

My question
To sum up, my question is whether it is possible to pass a BindingSource from the repository-cass (where the SQL-connection and queries are done), to my presenter, to my WinForm, which will use it to fill the DataGridView.
If this is not possible, is there an alternative way to keep my MVP- and repositorystructure, keep my DataGridView private and still fill it with database-data?

If the question is not clear, please ask for details. Thanks in advance!

Found a working solution. For those interested:

The datasource of the bindingsource is a DataTable. This DataTable is filled using a DataAdapter which executes SqlCommands. The DataTable can be passed as an parameter. I constructed my presenter-function like this, which is called when the user presses a button:

public void load_tableData()
    {
        FactuurRepository repository = new FactuurRepository();
        DataTable table = repository.getDataTable();
        screen.load_tableData(table);
    }

The repository function getDataTable will look something like this:

try
        {
            String selectCommand = "Enter selectcommand here";
            String connectionString = "Enter connectionString here";
            SqlDataAdapter adapter = new SqlDataAdapter(selectCommand, connectionString);
            DataTable table = new DataTable();
            adapter.Fill(table);
            return table;
        }

Finally, the code in my Form turns out like this:

public void load_tableData(DataTable table)
    {
        BindingSource binding = new BindingSource();
        binding.DataSource = table;
        dataGridView.DataSource = binding;
        dataGridView.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCellsExceptHeader);
    }

There are many ways to implement MVP and it would be silly to say one is right and one is wrong. The main idea though, is that your View and Presenter only know about each other via interfaces. This loose coupling then allows us to unit test the presentation layer and sometimes the model layer.

The way you have it implemented looks pretty good for MVP and closely matches how my earlier MVP code looked. Currently I'm trying to reduce my code in the View and to make MVP a little more similar to MVVM when possible. Usually for setting control data sources these days I just expose a simple property. Since most grids accept a DataTable as a source, it might look something like this:

public Object CustomerGridDataSource
{
    get
    {
        return CustomerGrid.DataSource;
    }
    set (Object value)
    {
        CustomerGrid.DataSource = value;
    }
}

Of course there will still be a requirement to configure grid columns and other interface tasks, but even this I have moved out of the View to a configuration system of classes that handle common configuration steps.

Anyway, good work on your solution. I just wanted to add some additional thoughts to the discussion.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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