Question

I have a form that contains a filtered datagridview (that hides entries marked "closed") based on a dataset and tableadapter from a MySQL database. I am stuck on one part that involves the launching of a dialog form which contains another datagridview based on the same dataset which displays all the entries in the table. I would like to be able to mark a selection of those "closed" with the checkboxcolumn, click a "close these records" button, close that dialog and have those changes reflected in the filtered datagridview.

I have tried multiple ways of implementing this and have had no luck. Basically, the closest attempt resulted in a null dataset when I returned back to the filtered datagridview....

My filtered datagridview is filled here:

this.dtClientTableAdapter.FillBy(this.DS.dtClient);

The dialog is launched here:

private void closeToolStripMenuItem_Click(object sender, EventArgs e)
    {
        CloseAgreement dlgCloseAgree = new CloseAgreement();
        dlgCloseAgree.ShowDialog();
        refreshRecords();
    }

The unfiltered datagridview is displayed in the dialog and filled here:

this.dtClientTableAdapter.Fill(this.DS.dtClient);

To set the changes the RowValidated event is used:

private void dataGridView1_RowValidated(object sender, DataGridViewCellEventArgs e)
    {
        DataTable changes = ((DataTable)dataGridView1.DataSource).GetChanges();

        if (changes != null)
        {
            MySqlCommandBuilder mcb = new MySqlCommandBuilder(mySqlDataAdapter);
            mySqlDataAdapter.UpdateCommand = mcb.GetUpdateCommand();
            mySqlDataAdapter.Update(changes);
            ((DataTable)dataGridView1.DataSource).AcceptChanges();
        }         
    }

Everything appears to work fine until that dialog is closed. When returning to the filtered datagridview in the first form, the datagridview is empty and refreshing by refilling the tableadapter is uneventful. Upon debugging, the entire dataset is null when closing the dialog form which explains the empty datagridview. Interestingly though, when the dialog is closed and no changes were made, then the filtered datagrid in the first form is still in tact. Several other different methods were tried with no workable result.

I have omitted the designer declarations, but if that is needed for clarification, I can edit the question.

I must be overlooking something simple. Is this even the right approach? Any help is appreciated.

Was it helpful?

Solution

I figured it out... The first dgv is more of a dashboard of open records. The second dgv is a listing of all the ones stored in the database. I want to be able to "open" and "close" records and to not see the "closed" ones in the dashboard, but still want the ability to open them back up at some point and also keep track of all the previously closed ones. My problem was that I was trying to use the same dataset for both dgv's. Once I created an independent dataset and queried the database, I was able to make the changes, update and return to the dashboard to see the changes. Just a huge goof on my part. This is the first mysql data driven app I have created, so there has been some major learning with the mysql connector. Thank you for your help though.

OTHER TIPS

An alternative way to filter Open/Closed records on the primary DataGridView is to provide a filter checkbox and simply filter the data.

Here is a crude example:

using System;
using System.Data;
using System.Windows.Forms;

class Form1 : Form
{
    DataGridView dgv;
    CheckBox hideCloseCheckBox;
    BindingSource bindingSource;

    public Form1()
    {
        /*
         * Add a DataGridView with a simulated DataSet
         * 
         * Note that we add a BindingSource between the DataSource member of the DGV and the DataSet.
         * We will use that BindingSource to filter the items.
         */
        Controls.Add((dgv = new DataGridView
        {
            Dock = DockStyle.Fill,

            AutoGenerateColumns = false,
            Columns =
            {
                new DataGridViewTextBoxColumn { Name = "Name", DataPropertyName = "Name", HeaderText = "Name", AutoSizeMode = DataGridViewAutoSizeColumnMode.Fill },
                new DataGridViewCheckBoxColumn { Name = "Open", DataPropertyName = "Open", HeaderText = "Open", AutoSizeMode = DataGridViewAutoSizeColumnMode.ColumnHeader },
            },

            DataSource = (bindingSource = new BindingSource(new DataSet
            {
                Tables =
                {
                    new DataTable("Table1")
                    {
                        Columns =
                        {
                            new DataColumn("Name", typeof(string)),
                            new DataColumn("Open", typeof(bool)),
                        },

                        Rows =
                        {
                            { "Item 1", true },
                            { "Item 2", false },
                            { "Item 3", true },
                            { "Item 4", false },
                            { "Item 5", true },
                        },
                    },
                },
            }, "Table1")),
        }));

        /*
         * Add a "Hide closed records" checkbox
         */
        Controls.Add((hideCloseCheckBox = new CheckBox
        {
            Dock = DockStyle.Top,
            Text = "Hide closed records",
            Padding = new Padding(20, 0, 0, 0),
        }));

        /*
         * When the user clicks that checkbox, we change the Filter on the BindingSource
         * 
         * See http://msdn.microsoft.com/en-us/library/cabd21yw.aspx for details on filter expressions.
         */
        hideCloseCheckBox.Click += (s, e) =>
            {
                if (hideCloseCheckBox.Checked)
                    bindingSource.Filter = "Open = true";
                else
                    bindingSource.Filter = "";
            };

        /*
         * The problem we have now is that when the user toggles the Open checkbox, the record doesn't
         * dissappear from view when the filter is enabled. This is because triggering the checkbox
         * doesn't change the row data until after the row is committed. This normally happens when
         * the user leaves the row. If you're allowing other editing on the row, this may be the 
         * desired behavior as you don't want the row to vanish mid-edit. However, if you do, you
         * can force the issue by causing a checkbox toggle to commit the row.
         */
        dgv.CellContentClick += (s, e) =>
            {
                // If the "Open" column is clicked
                if (dgv.Columns[e.ColumnIndex].Name == "Open")
                {
                    // Trigger EndEdit on the dgv and if that succeeds, trigger it on the bindingSource
                    if (dgv.EndEdit())
                        bindingSource.EndEdit();
                }
            };
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new Form1());
    }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top