4

This is c# windows forms.

I have a data grid view that is supposed to display two columns, file names, and modified date. The way that I'm doing this is through a task. I also have a class that hold only the file and path name, bindingsource, and data grid view. This task runs a method where the class is passed. Once the task is complete the class should have a grid view that I can then set to a gridview back on the form.

The class looks like this:

class GetLogFilesParameters
{
    public string FileNameandPath;
    public BindingSource BindingSource;
    public DataGridView GridView;

    public GetLogFilesParameters(string _fileNameAndPath)
    {
        FileNameandPath = _fileNameAndPath;
        BindingSource = new BindingSource();
        GridView = new DataGridView();
        GridView.DataSource = BindingSource;
    }
}

The method my task is calling look like this:

private static void GetLogFilesTest(GetLogFilesParameters FormFields)
    {
        Cursor.Current = Cursors.WaitCursor;

        try
        {
            //Setup data table
            DataTable FileList = new DataTable();
            FileList.Clear();
            DataColumn FileNameColumn = new DataColumn();
            FileNameColumn.ColumnName = "FileName";
            FileNameColumn.DataType = System.Type.GetType("System.String");

            DataColumn DateColumn = new DataColumn();
            DateColumn.ColumnName = "ModifiedDate";
            DateColumn.DataType = System.Type.GetType("System.DateTime");

            FileList.Columns.Add(FileNameColumn);
            FileList.Columns.Add(DateColumn);

            //Get a list of files in a directory
            string[] files = Directory.GetFiles(FormFields.FileNameandPath, "*.log");

            //Loop through the files and fill the data table with a row for each
            foreach (string file in files)
            {
                FileInfo FileInformation = new FileInfo(file);
                DataRow row = FileList.NewRow();
                row["FileName"] = FileInformation.Name;
                row["ModifiedDate"] = FileInformation.LastWriteTime;
                FileList.Rows.Add(row);
            }

            //FormFields.GridView.Columns.Add("FileName", "File Name");
            //FormFields.GridView.Columns.Add("ModifiedDate", "Modified Date");
            FormFields.GridView.AutoGenerateColumns = true;

            //Setup the binding source
            FormFields.BindingSource.DataSource = FileList;
            FormFields.BindingSource.Sort = "ModifiedDate DESC";

            FormFields.GridView.Columns[0].Width = (FormFields.GridView.Width / 10) * 6;
            FormFields.GridView.Columns[1].Width = (FormFields.GridView.Width / 10) * 4;
        }
        catch (Exception ex)
        {
            string ErrorText = "Error trying to get the list of log files." + Environment.NewLine + Environment.NewLine;
            ExceptionLogger.LogIt(ErrorText, "Exception");
            MessageBox.Show(ErrorText + ex.ToString());
        }
        finally
        {
            Cursor.Current = Cursors.Default;
        }
    }

My task looks like this:

GetLogFilesParameters GetLogFilesParameters = new GetLogFilesParameters(EpicorSenderPath);
            Task tGetFiles1 = new Task(() => GetLogFilesTest(GetLogFilesParameters));
            tGetFiles1.Start();
            tGetFiles1.ContinueWith((antecedent) =>
                {
                    gvEpicorSenderFiles = GetLogFilesParameters.GridView;
                }, TaskScheduler.FromCurrentSynchronizationContext());

The error I get is System.ArgumentOutOfRangeException: Index was out of range. Must be non-negative and less than the size of the collection. It happens in the method on this line:

FormFields.GridView.Columns[0].Width = (FormFields.GridView.Width / 10) * 6;

This is happening because the gridview doesn't have any columns according to the debug. Also, when it DOES have rows and data. I don't know what is wrong.

hondaman2003
  • 177
  • 2
  • 10
  • 1
    Not clear for me. Are you using async methods? – Chris Jun 07 '13 at 16:51
  • I'm sorry about my ignorance about your question. I am using a task for the first time and intend to call a method by passing a class previously instantiated. That part appears to be working. I wanted to include that because I wanted everyone to fully understand what was going on. – hondaman2003 Jun 07 '13 at 17:08
  • Ignorance is maybe from my side... Can you Try to move these lines of code in DataGridView.DataBindingComplete event? FormFields.GridView.Columns[0].Width = (FormFields.GridView.Width / 10) * 6; FormFields.GridView.Columns[1].Width = (FormFields.GridView.Width / 10) * 4; [1]: http://msdn.microsoft.com/en-us/library/system.windows.forms.datagridview.databindingcomplete.aspx – Chris Jun 07 '13 at 17:20
  • That worked. It's interesting that after you assign the datasource that the datagridview doesn't appear setup enough for you to be able to manipulate the columns that should be automatically generated. However I also believe that it's far better organization to have this type of code in that place anyway. – hondaman2003 Jun 07 '13 at 19:42
  • Can you put that as an answer so I can vote it up? – hondaman2003 Jun 07 '13 at 19:42

1 Answers1

3

I guess (I don't understand why exactly) you try to access Columns that do not exist yet.

Try to move these lines of code in DataGridView.DataBindingComplete event

FormFields.GridView.Columns[0].Width = (FormFields.GridView.Width / 10) * 6; 
FormFields.GridView.Columns[1].Width = (FormFields.GridView.Width / 10) * 4;
Chris
  • 8,527
  • 10
  • 34
  • 51