question

FriQenstein-7290 avatar image
0 Votes"
FriQenstein-7290 asked FriQenstein-7290 answered

Open File browser to Network location from Click in DataGridView

Greetings all,

I am wondering about adding a feature to my small application that will help the users simplify things.

Starter:
A portion of the program will generate a DataGridView(DGV) of Incoming and Outgoing invoices, as an end of month recap for managers. Occasionally, they want to look at the actual digital copies of the invoices, which I store on one of our network shares.

Prompt:
Is it possible to add an event to the DGV, so when a user clicks on one of the rows, it opens up a file browser that shows them the directory corresponding to that invoice reference listed in the DGV?

Problem:
Each entry in the DGV is pulled from a DB via SQL queries; so I will be putting the physical network drive link in the NOTES field of the table holding this data. I am thinking about parsing the NOTES field to retrieve the link, which will then be used in the event that triggers when the user clicks on a row in the DGV.

Thoughts? Or recommendations for a more simplistic approach that I may be overlooking?

Regards.


EDIT:
I have implemented the following as a temporary test, which seems to work in a very basic form.

 private void dgEoM_Invoices_CellContentClick(object sender, DataGridViewCellEventArgs e)
         {
             string folderPath = @"C:\Users\Steve Fontenot\Documents\Projects\Database _ WORKING";
                
             if (Directory.Exists(folderPath))
             {
                 ProcessStartInfo startInfo = new ProcessStartInfo
                 {
                     Arguments = folderPath,
                     FileName = "explorer.exe"
                 };
             Process.Start(startInfo);
             }
             else
             {
                 MessageBox.Show(string.Format("{0} Directory does not exist!", folderPath));
             }
         }

Now, I just need to figure out how to get the event to handle each row individually according to their network share link (physical network directory location).

dotnet-csharpvs-general
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

FriQenstein-7290 avatar image
0 Votes"
FriQenstein-7290 answered

Update:

Okay, after a little bit of cleanup and testing, I have come up with the following...

 private void dgEoM_Invoices_CellContentClick(object sender, DataGridViewCellEventArgs e)
         {
             Dictionary<string, string> dict = new Dictionary<string, string>
             {
                 {"01", "001_JAN" }, {"02", "002_FEB" }, {"03", "003_MAR" }, {"04", "004_APR" }, {"05", "005_MAY" }, {"06", "006_JUN" },
                 { "07", "007_JUL" }, {"08", "008_AUG" }, {"09", "009_SEP" }, {"10", "010_OCT" }, {"11", "011_NOV" }, {"12", "012_DEC" },
             };
             string keyValue;
             string folderPath = @"C:\Users\Steve Fontenot\Documents\Projects\Database _ WORKING\OUTGOING\";
             if (e.RowIndex >= 0)
             {
                 DataGridViewRow row = dgEoM_Invoices.Rows[e.RowIndex];
                 string company = row.Cells[0].Value.ToString();
                 string InvLocation2 = row.Cells[1].Value.ToString();
                 string[] invoiceMT = InvLocation2.Split('-');
                 string folderPath2 = (company + "\\MT " + InvLocation2 + "\\");
    
                 if (dict.TryGetValue(invoiceMT[1], out keyValue))
                 {
                     if (Directory.Exists(folderPath + company + "\\" + invoiceMT[0] + "\\" + keyValue + "\\MT " + InvLocation2 + "\\"))
                     {
                         ProcessStartInfo startInfo = new ProcessStartInfo
                         {
                             Arguments = (folderPath + company + "\\" + invoiceMT[0] + "\\" + keyValue + "\\MT " + InvLocation2 + "\\"),
                             FileName = "explorer.exe"
                         };
                         Process.Start(startInfo);
                     }
                     else
                     {
                         Console.WriteLine("NOT MATCHED!!!!!");
                         MessageBox.Show("ERROR!!! : The directory does not exist!");
                     }
                 }
    
             }
         }

I moved the if statement handling the directory check, so now it checks the entire string and notifies if the directory exits or not.
I also changed my approach on parsing out the information from the DGV after the user clicks it. It will read the cells containing the Company name and the invoice number, which is compared against a dictionary to account for the directory structure on the remote storage drive. It parses the invoice number string and determines the correct year and month, along with company name form another cell, and can locate the remote directory by splicing everything together.

It works for both methods, Incoming & Outgoing invoices, both generated from DGV event clicks and mapped to the corresponding directories.

I am still debating on adding a try/catch block, but for the moment, there is only 3 people using this little program, and of those 3, I am the primary user and the other two (for whom this feature was created) rarely utilize the program at all.

Alas, I am happy with the results and it is sufficient for their needs should they choose to use it.
Plus, I learned something in the process. :)

Regards. (marking this /solved)

5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

FriQenstein-7290 avatar image
0 Votes"
FriQenstein-7290 answered TimonYang-MSFT commented

Okay, so I have made a bit of progress.

I have changed the code above to the following:

 private void dgEoM_Invoices_CellContentClick(object sender, DataGridViewCellEventArgs e)
             {
                 string folderPath = @"C:\Users\Steve Fontenot\Documents\Projects\Database _ WORKING\";
                    
                 if (Directory.Exists(folderPath))
                 {
                     if (e.RowIndex >= 0)
                     {
                         DataGridViewRow row = dgEoM_Invoices.Rows[e.RowIndex];
                         string InvLocation1 = row.Cells[0].Value.ToString();
                         string InvLocation2 = row.Cells[1].Value.ToString();
                         string folderPath2 = (InvLocation1 + "\\MT " + InvLocation2 + "\\");
                         ProcessStartInfo startInfo = new ProcessStartInfo
                         {
                             Arguments = (folderPath + folderPath2),
                             FileName = "explorer.exe"
                         };
                         Process.Start(startInfo);
                         Console.WriteLine("File Path: " + folderPath + folderPath2);
                     }
                 }
                 else
                 {
                     MessageBox.Show(string.Format("{0} Directory does not exist!", folderPath));
                 }
             }

This essentially allows a user to click on a row, any part of the row, and it will parse the contents of the first and second cell, which contain the client name and invoice number, respectively. Since my naming convention on the network drive is pretty simplistic, I decided to go with this route for now.
The files are always stored on the same drive, and each client has their own folders for Incoming and Outgoing invoices. Inside each In/Out directory, each invoice has its own subdirectory.

So, I just string together the contents and apply it to the Argument being passed to the Process.Start() call so it opens the directly related to the row they clicked on.

This seems to work so far, but I will need to play with it a bit to ensure it holds together.

· 3
5 |1600 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

@FriQenstein-7290
I think this is a suitable approach. The only thing we need to pay attention to is that we need to consider possible access rights issues or other unexpected exceptions.
It is best to add a try-catch to catch these exceptions to prevent the program from accidentally crashing when the user uses it.

0 Votes 0 ·

Thank you for the feedback.

I am already implementing a few try/catch blocks now that I have more functionality.
I also need to rearrange the first if statement so that it can utilize the combined strings to check for validity after (within) the DGV string parse. I am using a combination of string.split and a dictionary for referencing the keys and values. (this part made it all so much easier)

Once I finish some of the logic and clean up the code I will post back. Any additional feedback is appreciated.

Thanks.

0 Votes 0 ·

@FriQenstein-7290
You are welcome, I look forward to your reply.

0 Votes 0 ·