Question : VS 2008 C# Make Non-Modal behave as Modal

I am developing a winform that works off an application that has a VS Toolkit. I created all of my forms as modal forms as I want processing to transfer to the called form while that form is open. I have discovered that there is a bug in that toolkit when it comes to modal forms. (the screen just freezes). I have been told to use non-modal forms and then control events to make a non-modal form behave like a modal form. My question is which events must I monitor so the user cannot leave the form until either pressing buttons on that form that allow them to leave. I have included the complete code below. This issue came up with the event tied to a datadridviewButtonCollumn I added that allows the user to lookup Job Numbers(frmLookupJob).
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
69:
70:
71:
72:
73:
74:
75:
76:
77:
78:
79:
80:
81:
82:
83:
84:
85:
86:
87:
88:
89:
90:
91:
92:
93:
94:
95:
96:
97:
98:
99:
100:
101:
102:
103:
104:
105:
106:
107:
108:
109:
110:
111:
112:
113:
114:
115:
116:
117:
118:
119:
120:
121:
122:
123:
124:
125:
126:
127:
128:
129:
130:
131:
132:
133:
134:
135:
136:
137:
138:
139:
140:
141:
142:
143:
144:
145:
146:
147:
148:
149:
150:
151:
152:
153:
154:
155:
156:
157:
158:
159:
160:
161:
162:
163:
164:
165:
166:
167:
168:
169:
170:
171:
172:
173:
174:
175:
176:
177:
178:
179:
180:
181:
182:
183:
184:
185:
186:
187:
188:
189:
190:
191:
192:
193:
194:
195:
196:
197:
198:
199:
200:
201:
202:
203:
204:
205:
206:
207:
208:
209:
210:
211:
212:
213:
214:
215:
216:
217:
218:
219:
220:
221:
222:
223:
224:
225:
226:
227:
228:
229:
230:
231:
232:
233:
234:
235:
236:
237:
238:
239:
240:
241:
242:
243:
244:
245:
246:
247:
248:
249:
250:
251:
252:
253:
254:
255:
256:
257:
258:
259:
260:
261:
262:
263:
264:
265:
266:
267:
268:
269:
270:
271:
272:
273:
274:
275:
276:
277:
278:
279:
280:
281:
282:
283:
284:
285:
286:
287:
288:
289:
290:
291:
292:
293:
294:
295:
296:
297:
298:
299:
300:
301:
302:
303:
304:
305:
306:
307:
308:
309:
310:
311:
312:
313:
314:
315:
316:
317:
318:
319:
320:
321:
322:
323:
324:
325:
326:
327:
328:
329:
330:
331:
332:
333:
334:
335:
336:
337:
338:
339:
340:
341:
342:
343:
344:
345:
346:
347:
348:
349:
350:
351:
352:
353:
354:
355:
356:
357:
358:
359:
360:
361:
362:
363:
364:
365:
366:
367:
368:
369:
370:
371:
372:
373:
374:
375:
376:
377:
378:
379:
380:
381:
382:
383:
384:
385:
386:
387:
388:
389:
390:
391:
392:
393:
394:
395:
396:
397:
398:
399:
400:
401:
402:
403:
404:
405:
406:
407:
408:
409:
410:
411:
412:
413:
414:
415:
416:
417:
418:
419:
420:
421:
422:
423:
424:
425:
426:
427:
428:
429:
430:
431:
432:
433:
434:
435:
436:
437:
438:
439:
440:
441:
442:
443:
444:
445:
446:
447:
448:
449:
450:
451:
452:
453:
454:
455:
456:
457:
458:
459:
460:
461:
462:
463:
464:
465:
466:
467:
468:
469:
470:
471:
472:
473:
474:
475:
476:
477:
478:
479:
480:
481:
482:
483:
484:
485:
486:
487:
488:
489:
490:
491:
492:
493:
494:
495:
496:
497:
498:
499:
500:
501:
502:
503:
504:
505:
506:
507:
508:
509:
510:
511:
512:
513:
514:
515:
=============================================================
OPENNING OF PROGRAM
=============================================================
namespace PopulateJobLinkerRTE
{
    public class GPAddIn : IDexterityAddIn
    {
        // IDexterityAddIn interface
        /* Keep a reference to the Receivables Transaction Entry Distribution screen */
        static frmViewJobLinker ViewJobLinkerForm;

        /* Create a reference to the Receivables Transaction Entry Distribution screen */
        static RmSalesDistributionForm RmSalesDistributionForm = Dynamics.Forms.RmSalesDistribution;
        static RmSalesDistributionForm.RmSalesDistributionWindow RmSalesDistributionWindow = RmSalesDistributionForm.RmSalesDistribution;

        
        public void Initialize()
        {
            /* Add the menu item to the Receivables Transaction Entry Distribution screen under Additional */
            /* This menu option will be View Job Linker GL Distributions CTRL-J */
            RmSalesDistributionForm.AddMenuHandler(ViewJobLinker, "View Job Linker Distributions", "J");
        }

        /* Method to open the View Batch GL Distributions from the Payables Batch Entry Window */
        public void ViewJobLinker(object sender, EventArgs e)
        {
            if (ViewJobLinkerForm == null || ViewJobLinkerForm.Created == false)
            {
                ViewJobLinkerForm = new frmViewJobLinker();
            }

            ViewJobLinkerForm.ShowDialog();
        }

    }
==============================================================
DISPLAY RECORDS AND PROVIDE LOOKUP WINDOW
==============================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Data.SqlClient;
using Microsoft.Dexterity.Bridge;
using Microsoft.Dexterity.Applications;
using Microsoft.Dexterity.Shell;
using Microsoft.Dexterity.Applications.DynamicsDictionary;

namespace PopulateJobLinkerRTE
{
    public partial class frmViewJobLinker : DexUIForm
    {

        /* Create a reference to the Receivables Transaction Entry screen */
        static RmSalesEntryForm RmSalesEntryForm = Dynamics.Forms.RmSalesEntry;
        static RmSalesEntryForm.RmSalesEntryWindow RmSalesEntryWindow = RmSalesEntryForm.RmSalesEntry;
        
        /* Create a reference to the Receivables Transaction Entry Distribution screen */
        static RmSalesDistributionForm RmSalesDistributionForm = Dynamics.Forms.RmSalesDistribution;
        static RmSalesDistributionForm.RmSalesDistributionWindow RmSalesDistributionWindow = RmSalesDistributionForm.RmSalesDistribution;

        /* Define a string variable to hold connection string */
        string ConnectionString;
                       
        /* Set up SQL Connection Handlers */
        private System.Data.SqlClient.SqlConnection DataConnection;
        private System.Data.DataSet DataDataSet;
        private System.Data.SqlClient.SqlCommand DataCommand;
        private System.Data.SqlClient.SqlDataAdapter DataDataAdapter;
        private System.Data.DataSet TrxTypeDataSet;
        private System.Data.SqlClient.SqlCommand TrxTypeDataCommand;
        private System.Data.SqlClient.SqlDataAdapter TrxTypeDataAdapter;
        private SqlCommandBuilder _commandBuilder;

        /* Define variables to hold batch number and batch source */
        string DocumentNumber;
        string MasterType;
        string DistSource;
        string DocSource;
        
        public frmViewJobLinker()
        {
            InitializeComponent();
                        
            txtCustomerID.Text = RmSalesEntryWindow.CustomerNumber;
            txtCustomerName.Text = RmSalesEntryWindow.CustomerName;
            txtDocumentNumber.Text = RmSalesEntryWindow.RmDocumentNumberWork;
            DocumentNumber = RmSalesEntryWindow.RmDocumentNumberWork;
            
            switch (RmSalesEntryWindow.DocumentType.Value.ToString())
            {
                case "1":
                    txtDocumentType.Text = "Sales/Invoices";
                    break;
                case "2":
                    txtDocumentType.Text = "Debit Memos";
                    break;
                case "3":
                    txtDocumentType.Text = "Finance Charges";
                    break;
                case "4":
                    txtDocumentType.Text = "Service/Repairs";
                    break;
                case "5":
                    txtDocumentType.Text = "Warranty";
                    break;
                case "6":
                    txtDocumentType.Text = "Credit Memo";
                    break;
                case "7":
                    txtDocumentType.Text = "Returns";
                    break;
                default:
                    txtDocumentType.Text = "Unknown";
                    break;
            }


            txtDocumentAmount.Text = RmSalesEntryWindow.DocumentAmount.Value.ToString("c");
            DocumentNumber = RmSalesEntryWindow.RmDocumentNumberWork;

            txtBatchName.Text = RmSalesEntryWindow.BatchNumber;
            /* Convert the posting date */
            txtPostingDate.Text = RmSalesEntryWindow.GlPostingDate.Value.ToString();
            try
            {

                if (txtPostingDate.Text != "")
                {
                    txtPostingDate.Text = Convert.ToDateTime(txtPostingDate.Text).ToString("MM/dd/yyyy");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR::" + ex.Message);
                this.Close();

            }
            /* Convert the document date */
            txtDocumentDate.Text = RmSalesEntryWindow.DocumentDate.Value.ToString();
            try
            {
                if (txtDocumentDate.Text.ToString() != "")
                {
                    txtDocumentDate.Text = Convert.ToDateTime(txtDocumentDate.Text).ToString("MM/dd/yyyy");
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR::" + ex.Message);
                this.Close();

            }


            MasterType = "CUS";
            DistSource = "Receivables Transaction Entry";
            DocSource = "Receivables";

            /* Populate the Job Linker table based on this Document Number */
            try
            {
                SqlConnection con = GetConnection();
                SqlCommand cmd = new SqlCommand();

                cmd.CommandType = CommandType.StoredProcedure;

                cmd.Parameters.Add(new SqlParameter("@DCMTNMBR", DocumentNumber));
                cmd.Parameters.Add(new SqlParameter("@MASTERTYPE", MasterType));
                cmd.Parameters.Add(new SqlParameter("@DISTSOURCE", DistSource));
                cmd.Parameters.Add(new SqlParameter("@DOCSOURCE", DocSource));

                cmd.CommandText = "rbsUpdateJobLinkerRTE";

                cmd.Connection = con;

                cmd.ExecuteNonQuery();

                con.Close();

            }
            catch (Exception ex)
            {
                MessageBox.Show("ERROR::" + ex.Message);
                this.Close();

            }

            /* Display the GL Distributions from the Job Linker table per Document Number */
            try
            {
                SqlConnection DataConnection = GetConnection();

                /* Define dataset for Transaction Types */
                TrxTypeDataSet = new System.Data.DataSet();
                TrxTypeDataSet.CaseSensitive = false;

                TrxTypeDataCommand = new System.Data.SqlClient.SqlCommand();
                TrxTypeDataCommand.Connection = DataConnection;

                TrxTypeDataCommand.CommandText = "select LTRIM(DISTTRXTYPE) AS DISTTRXTYPE from JOB_TRX_TYPES where formtype='SALES' ORDER BY DISTTRXTYPE";

                TrxTypeDataAdapter = new System.Data.SqlClient.SqlDataAdapter();
                TrxTypeDataAdapter.SelectCommand = TrxTypeDataCommand;

                TrxTypeDataAdapter.Fill(TrxTypeDataSet);

                /* Define dataset for GL distribution amounts */
                DataDataSet = new System.Data.DataSet();
                DataDataSet.CaseSensitive = false;

                DataCommand = new System.Data.SqlClient.SqlCommand();
                DataCommand.Connection = DataConnection;

                DataCommand.CommandText = "select JOBNUMBER,ACTNUMST,DEBITAMT,CRDTAMNT,DISTTYPE,DISTTRXTYPE,DISTREF,BCHSOURC,TRANSNMBR,TRXTYPE,DSTSQNUM,CNTRLTYP,APTVCHNM,SPCLDIST " +
                "from JOB_LINKER WHERE TRANSNMBR ='" + DocumentNumber + "' order by DSTSQNUM";

                DataDataAdapter = new System.Data.SqlClient.SqlDataAdapter();
                DataDataAdapter.SelectCommand = DataCommand;
                _commandBuilder = new SqlCommandBuilder(DataDataAdapter);

                DataDataAdapter.Fill(DataDataSet);

                dgvViewJobLinker.DataError += new DataGridViewDataErrorEventHandler(dgvJobLinker_DataError);

                dgvViewJobLinker.RowHeadersVisible = false;
                dgvViewJobLinker.DataSource = DataDataSet.Tables[0].DefaultView;
                dgvViewJobLinker.AutoGenerateColumns = true;
                dgvViewJobLinker.DefaultCellStyle.NullValue = ' ';
                dgvViewJobLinker.AllowUserToAddRows = false;

                DataGridViewButtonColumn colButton = new DataGridViewButtonColumn();
                colButton.HeaderText = "";
                colButton.Name = "btnLookupJob";
                colButton.Text = "Lookup Job";
                colButton.UseColumnTextForButtonValue = true;

                dgvViewJobLinker.Columns.Insert(0, colButton);
                dgvViewJobLinker.Columns[0].Width = 80;
               
                dgvViewJobLinker.Columns[1].Width = 100;
                dgvViewJobLinker.Columns[1].ReadOnly = false;
                dgvViewJobLinker.Columns[1].HeaderText = "Job Number";

                dgvViewJobLinker.Columns[2].Width = 100;
                dgvViewJobLinker.Columns[2].ReadOnly = true;
                dgvViewJobLinker.Columns[2].HeaderText = "GL Account";

                dgvViewJobLinker.Columns[3].Width = 84;
                dgvViewJobLinker.Columns[3].ReadOnly = true;
                dgvViewJobLinker.Columns[3].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                dgvViewJobLinker.Columns[3].DefaultCellStyle.Format = "c";
                dgvViewJobLinker.Columns[3].HeaderText = "Debit Amount";

                dgvViewJobLinker.Columns[4].Width = 84;
                dgvViewJobLinker.Columns[4].ReadOnly = true;
                dgvViewJobLinker.Columns[4].DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight;
                dgvViewJobLinker.Columns[4].DefaultCellStyle.Format = "c";
                dgvViewJobLinker.Columns[4].HeaderText = "Credit Amount";

                dgvViewJobLinker.Columns[5].Width = 100;
                dgvViewJobLinker.Columns[5].ReadOnly = true;
                dgvViewJobLinker.Columns[5].HeaderText = "Dist Type";

                /* Add a new Column (ComboBox) for the Transaction Type column */
                DataGridViewComboBoxColumn colType = new DataGridViewComboBoxColumn();

                colType.DefaultCellStyle.NullValue = " ";
                colType.DataSource = TrxTypeDataSet.Tables[0];
                colType.ValueMember = DataDataSet.Tables[0].Columns[5].ColumnName.ToString();
                colType.DisplayMember = colType.ValueMember;
                colType.HeaderText = "Transaction Type";
                colType.DropDownWidth = 90;
                colType.Width = 90;
                colType.MaxDropDownItems = 7;
                colType.DataPropertyName = DataDataSet.Tables[0].Columns[5].ColumnName.ToString();
                colType.Name = DataDataSet.Tables[0].Columns[5].ColumnName.ToString();
                dgvViewJobLinker.Columns.RemoveAt(6);
                dgvViewJobLinker.Columns.Insert(6, colType);

                dgvViewJobLinker.Columns[7].Width = 292;
                dgvViewJobLinker.Columns[7].ReadOnly = false;
                dgvViewJobLinker.Columns[7].HeaderText = "Dist Reference";

                dgvViewJobLinker.Columns[8].Visible = false;
                dgvViewJobLinker.Columns[9].Visible = false;
                dgvViewJobLinker.Columns[10].Visible = false;
                dgvViewJobLinker.Columns[11].Visible = false;
                dgvViewJobLinker.Columns[12].Visible = false;
                dgvViewJobLinker.Columns[13].Visible = false;
                dgvViewJobLinker.Columns[14].Visible = false;

                dgvViewJobLinker.EditMode = DataGridViewEditMode.EditOnEnter;
                dgvViewJobLinker.Focus();

            }
            catch (Exception ex)
            {
                MessageBox.Show("Error: " + ex.Message);
            }

        }

        private void btnExit_Click(object sender, EventArgs e)
        {
            this.Hide();
            DataConnection.Close();
            
        }

        private SqlConnection GetConnection()
        {
            /* Create reader and open file containing connection string */
            TextReader tr = new StreamReader(@"C:\Program Files\Microsoft Dynamics\GP\Addins\GSE.INI");

            /* Read line containing the connection string */
            ConnectionString = tr.ReadLine();

            /* Close the stream */
            tr.Close();

            DataConnection = new System.Data.SqlClient.SqlConnection(ConnectionString);
            DataConnection.Open();

            return DataConnection;
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            try
            {
                //DataCommandBuilder = new SqlCommandBuilder(DataDataAdapter);
                //DataDataAdapter.DeleteCommand = DataCommandBuilder.GetDeleteCommand();
                //DataDataAdapter.InsertCommand = DataCommandBuilder.GetInsertCommand();
                //DataDataAdapter.UpdateCommand = DataCommandBuilder.GetUpdateCommand();
                _commandBuilder.GetUpdateCommand();

                DataDataAdapter.Update(DataDataSet);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            this.Hide();
            DataConnection.Close();
            
        }

        private void dgvJobLinker_DataError(object sender, DataGridViewDataErrorEventArgs anError)
        {
            
        }

        private void dgvViewJobLinker_CellContentClick(object sender, DataGridViewCellEventArgs e)
        {
            if (e.ColumnIndex == 0 && e.RowIndex >= 0)
            {

                    using (frmLookupJob ViewAgenciesByJobsForm = new frmLookupJob())
                    {
                        if (ViewAgenciesByJobsForm.ShowDialog(this) == DialogResult.OK)
                            dgvViewJobLinker[1, dgvViewJobLinker.CurrentCell.RowIndex].Value = ViewAgenciesByJobsForm.CellValue;
                    }  
            }
        }
        }
    }
==============================================================
LOOKUP WINDOW
==============================================================
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Microsoft.Dexterity.Bridge;
using Microsoft.Dexterity.Applications;
using Microsoft.Dexterity.Shell;

namespace PopulateJobLinkerRTE
{
    public partial class frmLookupJob : DexUIForm
    {
        
        /* Define a string variable to hold the connection string */
        string ConnectionString;

        /* Define variables used in string search */
        string strSearch = "";
        int i;

        /* Set up SQL Connection handlers */
        private System.Data.SqlClient.SqlConnection DataConnection;
        private System.Data.DataSet DataDataSet;
        private System.Data.SqlClient.SqlCommand DataCommand;
        private System.Data.SqlClient.SqlDataAdapter DataDataAdapter;
        public string CellValue { get; set; }
      
        public frmLookupJob()
        {
            InitializeComponent();
                                  
            try
            {
                SqlConnection DataConnection = GetConnection();

                DataDataSet = new System.Data.DataSet();
                DataDataSet.CaseSensitive = false;

                DataCommand = new System.Data.SqlClient.SqlCommand();
                DataCommand.Connection = DataConnection;

                DataCommand.CommandText = "SELECT JOBNUMBER,AGENCY FROM JOBS ORDER BY JOBNUMBER";

                DataDataAdapter = new System.Data.SqlClient.SqlDataAdapter();
                DataDataAdapter.SelectCommand = DataCommand;
                DataDataAdapter.TableMappings.Add("Table", "AgenciesByJobs");
                DataDataAdapter.Fill(DataDataSet);

                dgvAgenciesByJobs.ReadOnly = false;
                dgvAgenciesByJobs.RowHeadersVisible = false;
                dgvAgenciesByJobs.AllowUserToResizeColumns = false;
                dgvAgenciesByJobs.AllowUserToResizeRows = false;

                dgvAgenciesByJobs.DataSource = DataDataSet.Tables["AgenciesByJobs"].DefaultView;
                dgvAgenciesByJobs.Columns[0].Width = 85;
                dgvAgenciesByJobs.Columns[0].HeaderText = "Job Number";
                dgvAgenciesByJobs.Columns[0].ReadOnly = true;
                dgvAgenciesByJobs.Columns[1].Width = 95;
                dgvAgenciesByJobs.Columns[1].HeaderText = "Agency Code";
                dgvAgenciesByJobs.Columns[1].ReadOnly = true;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
                   
        }
        
        private void btnExit_Click(object sender, EventArgs e)
        {
            DialogResult = DialogResult.Cancel;
            DataConnection.Close();
            this.Close();
            return;
        }

        private SqlConnection GetConnection()
        {
            /* Create reader and open file containing connection string */
            TextReader tr = new StreamReader(@"C:\Program Files\Microsoft Dynamics\GP\Addins\GSE2000.INI");

            /* Read line containing the connection string */
            ConnectionString = tr.ReadLine();

            /* Close the stream */
            tr.Close();

            DataConnection = new System.Data.SqlClient.SqlConnection(ConnectionString);
            DataConnection.Open();

            return DataConnection;
        }

        private void dgvAgenciesByJobs_DoubleClick(object sender, EventArgs e)
        {
            int CurrentRow;

            CurrentRow = dgvAgenciesByJobs.CurrentCell.RowIndex;
            dgvAgenciesByJobs.CurrentCell = dgvAgenciesByJobs[0, CurrentRow];
            CellValue = dgvAgenciesByJobs.CurrentCell.Value.ToString();
            DialogResult = DialogResult.OK;
            strSearch = "";

            DataConnection.Close();
            this.Close();
            return;

        }

        private void dgvAgenciesByJobs_KeyPress(object sender, KeyPressEventArgs e)
        {
            strSearch += e.KeyChar;

            if (e.KeyChar == (char)Keys.Back)
            {
                if (strSearch.Length > 0) strSearch = strSearch.Substring(0, strSearch.Length - 2);
            }

            for (i = 0; i <= dgvAgenciesByJobs.RowCount - 1; i++)
            {
                if (dgvAgenciesByJobs[0, i].Value != null && dgvAgenciesByJobs[0, i].Value.ToString().StartsWith(strSearch.ToUpper()))
                {
                    dgvAgenciesByJobs.Rows[i].Selected = true;
                    dgvAgenciesByJobs.CurrentCell = dgvAgenciesByJobs[0, i];
                    if (dgvAgenciesByJobs.Rows[i].Displayed == false)
                    {
                        dgvAgenciesByJobs.FirstDisplayedScrollingRowIndex = i;
                    }
                    return;
                }
            }        
        }
    }
    
}

Answer : VS 2008 C# Make Non-Modal behave as Modal

(In MS Access VBA) To set the focus onto any open form, the syntax is:

   Forms!YourFormName.SetFocus

Hope this helps as well.

;-)

JeffCoachman
Random Solutions  
 
programming4us programming4us