Ejemplo n.º 1
0
        private void ButUpdateProvs_Click(object sender, EventArgs e)
        {
            if (IsNew)
            {
                MsgBox.Show(this, "Not for new operatories.");
                return;
            }
            //Check against cache. Instead of saving changes, make them get out and reopen. Safer and simpler.
            Operatory op = Operatories.GetOperatory(OpCur.OperatoryNum);

            if (op.OpName != textOpName.Text ||
                op.Abbrev != textAbbrev.Text ||
                op.IsHidden != checkIsHidden.Checked ||
                op.ClinicNum != comboClinic.SelectedClinicNum ||
                op.ProvDentist != comboProv.GetSelectedProvNum() ||
                op.ProvHygienist != comboHyg.GetSelectedProvNum() ||
                op.IsHygiene != checkIsHygiene.Checked ||
                op.SetProspective != checkSetProspective.Checked ||
                op.IsWebSched != checkIsWebSched.Checked)
            {
                MsgBox.Show(this, "Changes were detected above.  Save all changes, get completely out of the operatories window, and then re-enter.");
                return;
            }
            if (!Security.IsAuthorized(Permissions.Setup) || !Security.IsAuthorized(Permissions.AppointmentEdit))
            {
                return;
            }
            //Operatory operatory=Operatories.GetOperatory(contrApptPanel.OpNumClicked);
            if (Security.CurUser.ClinicIsRestricted && !Clinics.GetForUserod(Security.CurUser).Exists(x => x.ClinicNum == OpCur.ClinicNum))
            {
                MsgBox.Show(this, "You are restricted from accessing the clinic belonging to the selected operatory.  No changes will be made.");
                return;
            }
            if (!MsgBox.Show(this, MsgBoxButtons.YesNo,
                             "WARNING: We recommend backing up your database before running this tool.  "
                             + "This tool may take a very long time to run and should be run after hours.  "
                             + "In addition, this tool could potentially change hundreds of appointments.  "
                             + "The changes made by this tool can only be manually reversed.  "
                             + "Are you sure you want to continue?"))
            {
                return;
            }
            SecurityLogs.MakeLogEntry(Permissions.Setup, 0, Lan.g(this, "Update Provs on Future Appts tool run on operatory ") + OpCur.Abbrev + ".");
            List <Appointment> listAppts = Appointments.GetAppointmentsForOpsByPeriod(new List <long>()
            {
                OpCur.OperatoryNum
            }, DateTime.Now);                                                                                                                      //no end date, so all future
            List <Appointment> listApptsOld = new List <Appointment>();

            foreach (Appointment appt in listAppts)
            {
                listApptsOld.Add(appt.Copy());
            }
            ContrApptRef.MoveAppointments(listAppts, listApptsOld, OpCur);
            MsgBox.Show(this, "Done");
        }
Ejemplo n.º 2
0
        ///<summary>When looking at a daily appointment module and the current appointment view is has 'OnlyScheduleProvs' turned on, this method will dynamically add additional operatories to visOps for providers that are scheduled to work.</summary>
        public static void AddOpsForScheduledProvs(bool isWeekly, List <Schedule> dailySched, ApptView apptViewCur, ref List <Operatory> visOps)
        {
            //if this appt view has the option to show only scheduled providers and this is daily view.
            //Remember that there is no intelligence in weekly view for this option, and it behaves just like it always did.
            if (ApptViews.IsNoneView(apptViewCur) ||
                dailySched == null ||
                visOps == null ||
                !apptViewCur.OnlyScheduledProvs ||
                isWeekly)
            {
                return;
            }
            //intelligently decide what ops to show.  It's based on the schedule for the day.
            //visOps will be totally empty right now because it looped out of the above section of code.
            List <long>      listSchedOps;
            bool             opAdded;
            int              indexOp;
            List <Operatory> listOpsShort       = Operatories.GetDeepCopy(true);
            List <long>      listApptViewOpNums = ApptViewItems.GetOpsForView(apptViewCur.ApptViewNum);

            for (int i = 0; i < listOpsShort.Count; i++)       //loop through all ops for all views (except the hidden ones, of course)
            //If this operatory was not one of the selected Ops from the Appt View Edit window, skip it.
            {
                if (!listApptViewOpNums.Contains(listOpsShort[i].OperatoryNum))
                {
                    continue;
                }
                //find any applicable sched for the op
                opAdded = false;
                for (int s = 0; s < dailySched.Count; s++)
                {
                    if (dailySched[s].SchedType != ScheduleType.Provider)
                    {
                        continue;
                    }
                    if (dailySched[s].StartTime == new TimeSpan(0))                   //skip if block starts at midnight.
                    {
                        continue;
                    }
                    if (dailySched[s].StartTime == dailySched[s].StopTime)                   //skip if block has no length.
                    {
                        continue;
                    }
                    if (apptViewCur.OnlySchedAfterTime > new TimeSpan(0, 0, 0))
                    {
                        if (dailySched[s].StartTime < apptViewCur.OnlySchedAfterTime ||
                            dailySched[s].StopTime < apptViewCur.OnlySchedAfterTime)
                        {
                            continue;
                        }
                    }
                    if (apptViewCur.OnlySchedBeforeTime > new TimeSpan(0, 0, 0))
                    {
                        if (dailySched[s].StartTime > apptViewCur.OnlySchedBeforeTime ||
                            dailySched[s].StopTime > apptViewCur.OnlySchedBeforeTime)
                        {
                            continue;
                        }
                    }
                    //this 'sched' must apply to this situation.
                    //listSchedOps is the ops for this 'sched'.
                    listSchedOps = dailySched[s].Ops;
                    //Add all the ops for this 'sched' to the list of visible ops
                    for (int p = 0; p < listSchedOps.Count; p++)
                    {
                        //Filter the ops if the clinic option was set for the appt view.
                        if (apptViewCur.ClinicNum > 0 && apptViewCur.ClinicNum != Operatories.GetOperatory(listSchedOps[p]).ClinicNum)
                        {
                            continue;
                        }
                        if (listSchedOps[p] == listOpsShort[i].OperatoryNum)
                        {
                            Operatory op = listOpsShort[i];
                            indexOp = Operatories.GetOrder(listSchedOps[p]);
                            if (indexOp != -1 && !visOps.Contains(op))                           //prevents adding duplicate ops
                            {
                                visOps.Add(op);
                                opAdded = true;
                                break;
                            }
                        }
                    }
                    //If the provider is not scheduled to any op(s), add their default op(s).
                    if (listOpsShort[i].ProvDentist == dailySched[s].ProvNum && listSchedOps.Count == 0)                 //only if the sched does not specify any ops
                    //Only add the op if the clinic option was not set in the appt view or if the op is assigned to that clinic.
                    {
                        if (apptViewCur.ClinicNum == 0 || apptViewCur.ClinicNum == listOpsShort[i].ClinicNum)
                        {
                            indexOp = Operatories.GetOrder(listOpsShort[i].OperatoryNum);
                            if (indexOp != -1 && !visOps.Contains(listOpsShort[i]))
                            {
                                visOps.Add(listOpsShort[i]);
                                opAdded = true;
                            }
                        }
                    }
                    if (opAdded)
                    {
                        break;                        //break out of the loop of schedules.  Continue with the next op.
                    }
                }
            }
            //Remove any duplicates before return.
            visOps = visOps.GroupBy(x => x.OperatoryNum).Select(x => x.First()).ToList();
        }
Ejemplo n.º 3
0
        ///<summary>Offers to use unscheduled appt.  Shows ApptEdit window. Sets Prospective, if necessary.  Fires Automation triggers.  ListAptNumsSelected will contain the AptNum of the new appointment.</summary>
        public void MakeAppointment()
        {
            //Check to see if the patient has any unscheduled appointments and inform the user.
            List <Appointment> listUnschedAppts = Appointments.GetUnschedApptsForPat(_patCur.PatNum);

            //Per Nathan, pinboard appointments will not be considered unscheduled for this logic.
            listUnschedAppts.RemoveAll(x => x.AptNum.In(_listPinboardApptNums));
            FormApptEdit formApptEdit            = null;
            long         aptNum                  = 0;
            bool         isSchedulingUnscheduled = false;

            if (listUnschedAppts.Count > 0 &&
                MsgBox.Show(this, MsgBoxButtons.YesNo, "This patient has an unscheduled appointment, would you like to use an existing unscheduled appointment?"))
            {
                if (listUnschedAppts.Count == 1)
                {
                    aptNum = listUnschedAppts[0].AptNum;
                }
                else                  //Multiple unscheduled appointments, let the user pick which one to use.
                {
                    FormUnschedListPatient formUnschedListPatient = new FormUnschedListPatient(_patCur);
                    if (formUnschedListPatient.ShowDialog() != DialogResult.OK)
                    {
                        return;
                    }
                    //Use the appointment the user selected.
                    aptNum = formUnschedListPatient.SelectedAppt.AptNum;
                }
                isSchedulingUnscheduled = true;
            }
            formApptEdit       = new FormApptEdit(aptNum, patNum: _patCur.PatNum, useApptDrawingSettings: IsInitialDoubleClick, patient: _patCur, dateTNew: DateTNew, opNumNew: OpNumNew);
            formApptEdit.IsNew = (aptNum == 0);
            formApptEdit.IsSchedulingUnscheduledAppt = isSchedulingUnscheduled;
            formApptEdit.ShowDialog();
            if (formApptEdit.DialogResult != DialogResult.OK)
            {
                return;
            }
            Appointment aptCur = formApptEdit.GetAppointmentCur();

            if (IsInitialDoubleClick)
            {
                if (isSchedulingUnscheduled)                 //User double clicked in Appointment Module, intending to schedule appointment at a specific time/op/etc.
                {
                    Appointment aptOld = aptCur.Copy();
                    aptCur.AptDateTime = DateTimeClicked;
                    aptCur.Op          = OpNumClicked;
                    if (_patCur != null && _patCur.AskToArriveEarly > 0)
                    {
                        aptCur.DateTimeAskedToArrive = aptCur.AptDateTime.AddMinutes(-_patCur.AskToArriveEarly);
                    }
                    aptCur           = Appointments.AssignFieldsForOperatory(aptCur);
                    aptCur.AptStatus = ApptStatus.Scheduled;
                    Appointments.Update(aptCur, aptOld);
                }
                //Change PatStatus to Prospective or from Prospective.
                Operatory opCur = Operatories.GetOperatory(aptCur.Op);
                if (opCur != null)
                {
                    if (opCur.SetProspective && _patCur.PatStatus != PatientStatus.Prospective)                    //Don't need to prompt if patient is already prospective.
                    {
                        if (MsgBox.Show(this, MsgBoxButtons.OKCancel, "Patient's status will be set to Prospective."))
                        {
                            Patient patOld = _patCur.Copy();
                            _patCur.PatStatus = PatientStatus.Prospective;
                            Patients.Update(_patCur, patOld);
                        }
                    }
                    else if (!opCur.SetProspective && _patCur.PatStatus == PatientStatus.Prospective)
                    {
                        if (MsgBox.Show(this, MsgBoxButtons.OKCancel, "Patient's status will change from Prospective to Patient."))
                        {
                            Patient patOld = _patCur.Copy();
                            _patCur.PatStatus = PatientStatus.Patient;
                            Patients.Update(_patCur, patOld);
                        }
                    }
                }
            }
            ListAptNumsSelected.Add(aptCur.AptNum);
            if (IsInitialDoubleClick)
            {
                _otherResult = OtherResult.CreateNew;
            }
            else
            {
                _otherResult = OtherResult.NewToPinBoard;
            }
            if (aptCur.IsNewPatient)
            {
                AutomationL.Trigger(AutomationTrigger.CreateApptNewPat, null, aptCur.PatNum, aptCur.AptNum);
            }
            AutomationL.Trigger(AutomationTrigger.CreateAppt, null, aptCur.PatNum, aptCur.AptNum);
            DialogResult = DialogResult.OK;
        }
Ejemplo n.º 4
0
        private void butNew_Click(object sender, System.EventArgs e)
        {
            Appointment AptCur = new Appointment();

            AptCur.PatNum = PatCur.PatNum;
            if (PatCur.DateFirstVisit.Year < 1880 &&
                !Procedures.AreAnyComplete(PatCur.PatNum))                   //this only runs if firstVisit blank
            {
                AptCur.IsNewPatient = true;
            }
            AptCur.Pattern = "/X/";
            if (PatCur.PriProv == 0)
            {
                AptCur.ProvNum = PIn.PInt(((Pref)PrefB.HList["PracticeDefaultProv"]).ValueString);
            }
            else
            {
                AptCur.ProvNum = PatCur.PriProv;
            }
            AptCur.ProvHyg   = PatCur.SecProv;
            AptCur.AptStatus = ApptStatus.Scheduled;
            AptCur.ClinicNum = PatCur.ClinicNum;
            if (InitialClick)            //initially double clicked on appt module
            {
                DateTime d;
                if (ContrApptSheet.IsWeeklyView)
                {
                    d = ContrAppt.WeekStartDate.AddDays(ContrAppt.SheetClickedonDay);
                }
                else
                {
                    d = Appointments.DateSelected;
                }
                int minutes = (int)(ContrAppt.SheetClickedonMin / ContrApptSheet.MinPerIncr) * ContrApptSheet.MinPerIncr;
                AptCur.AptDateTime = new DateTime(d.Year, d.Month, d.Day
                                                  , ContrAppt.SheetClickedonHour, minutes, 0);
                AptCur.Op = ContrAppt.SheetClickedonOp;
                Operatory curOp = Operatories.GetOperatory(AptCur.Op);
                if (curOp.ProvDentist != 0)
                {
                    AptCur.ProvNum = curOp.ProvDentist;
                }
                AptCur.ProvHyg   = curOp.ProvHygienist;
                AptCur.IsHygiene = curOp.IsHygiene;
                AptCur.ClinicNum = curOp.ClinicNum;
                try {
                    Appointments.InsertOrUpdate(AptCur, null, true);
                }
                catch (ApplicationException ex) {
                    MessageBox.Show(ex.Message);
                }
            }
            else
            {
                //new appt will be placed on pinboard instead of specific time
            }
            try{
                Appointments.InsertOrUpdate(AptCur, null, true);
            }
            catch (ApplicationException ex) {
                MessageBox.Show(ex.Message);
                return;
            }
            FormApptEdit FormApptEdit2 = new FormApptEdit(AptCur.AptNum);

            FormApptEdit2.IsNew = true;
            FormApptEdit2.ShowDialog();
            if (FormApptEdit2.DialogResult != DialogResult.OK)
            {
                return;
            }
            AptSelected = AptCur.AptNum;
            if (InitialClick)
            {
                oResult = OtherResult.CreateNew;
            }
            else
            {
                oResult = OtherResult.NewToPinBoard;
            }
            DialogResult = DialogResult.OK;
        }
Ejemplo n.º 5
0
        ///<summary>Gets (list)ForCurView, ApptDrawing.VisOps, ApptDrawing.VisProvs, and ApptRows.  Also sets TwoRows. Works even if supply -1 to indicate no apptview is selected.  Pass in null for the dailySched if this is a weekly view or if in FormApptViewEdit.</summary>
        public static void GetForCurView(ApptView av, bool isWeekly, List <Schedule> dailySched)
        {
            ApptViewCur          = av;
            ForCurView           = new List <ApptViewItem>();
            ApptDrawing.VisProvs = new List <Provider>();
            ApptDrawing.VisOps   = new List <Operatory>();
            ApptRows             = new List <ApptViewItem>();
            int index;

            //If there are no appointment views set up (therefore, none selected), then use a hard-coded default view.
            if (ApptViewCur == null)
            {
                //MessageBox.Show("apptcategorynum:"+ApptCategories.Cur.ApptCategoryNum.ToString());
                //make visible ops exactly the same as the short ops list (all except hidden)
                for (int i = 0; i < OperatoryC.ListShort.Count; i++)
                {
                    ApptDrawing.VisOps.Add(OperatoryC.ListShort[i]);
                }
                //make visible provs exactly the same as the prov list (all except hidden)
                for (int i = 0; i < ProviderC.ListShort.Count; i++)
                {
                    ApptDrawing.VisProvs.Add(ProviderC.ListShort[i]);
                }
                //Hard coded elements showing
                ApptRows.Add(new ApptViewItem("PatientName", 0, Color.Black));
                ApptRows.Add(new ApptViewItem("ASAP", 1, Color.DarkRed));
                ApptRows.Add(new ApptViewItem("MedUrgNote", 2, Color.DarkRed));
                ApptRows.Add(new ApptViewItem("PremedFlag", 3, Color.DarkRed));
                ApptRows.Add(new ApptViewItem("Lab", 4, Color.DarkRed));
                ApptRows.Add(new ApptViewItem("Procs", 5, Color.Black));
                ApptRows.Add(new ApptViewItem("Note", 6, Color.Black));
                ApptDrawing.RowsPerIncr = 1;
            }
            //An appointment view is selected, so add provs and ops from the view to our lists of indexes.
            else
            {
                for (int i = 0; i < ApptViewItemC.List.Length; i++)
                {
                    if (ApptViewItemC.List[i].ApptViewNum == ApptViewCur.ApptViewNum)
                    {
                        ForCurView.Add(ApptViewItemC.List[i]);
                        if (ApptViewItemC.List[i].OpNum > 0)                      //op
                        {
                            if (ApptViewCur.OnlyScheduledProvs && !isWeekly)
                            {
                                continue;                                //handled below
                            }
                            index = Operatories.GetOrder(ApptViewItemC.List[i].OpNum);
                            if (index != -1)
                            {
                                ApptDrawing.VisOps.Add(OperatoryC.ListShort[index]);
                            }
                        }
                        else if (ApptViewItemC.List[i].ProvNum > 0)                      //prov
                        {
                            index = Providers.GetIndex(ApptViewItemC.List[i].ProvNum);
                            if (index != -1)
                            {
                                ApptDrawing.VisProvs.Add(ProviderC.ListShort[index]);
                            }
                        }
                        else                         //element or apptfielddef
                        {
                            ApptRows.Add(ApptViewItemC.List[i]);
                        }
                    }
                }
                ApptDrawing.RowsPerIncr = ApptViewCur.RowsPerIncr;
            }
            //if this appt view has the option to show only scheduled providers and this is daily view.
            //Remember that there is no intelligence in weekly view for this option, and it behaves just like it always did.
            if (ApptViewCur != null && ApptViewCur.OnlyScheduledProvs && !isWeekly)
            {
                //intelligently decide what ops to show.  It's based on the schedule for the day.
                //VisOps will be totally empty right now because it looped out of the above section of code.
                List <long> listSchedOps;
                bool        opAdded;
                int         indexOp;
                for (int i = 0; i < OperatoryC.ListShort.Count; i++)          //loop through all ops for all views (except the hidden ones, of course)
                //find any applicable sched for the op
                {
                    opAdded = false;
                    for (int s = 0; s < dailySched.Count; s++)
                    {
                        if (dailySched[s].SchedType != ScheduleType.Provider)
                        {
                            continue;
                        }
                        if (dailySched[s].StartTime == new TimeSpan(0))                       //skip if block starts at midnight.
                        {
                            continue;
                        }
                        if (dailySched[s].StartTime == dailySched[s].StopTime)                       //skip if block has no length.
                        {
                            continue;
                        }
                        if (ApptViewCur.OnlySchedAfterTime > new TimeSpan(0, 0, 0))
                        {
                            if (dailySched[s].StartTime < ApptViewCur.OnlySchedAfterTime ||
                                dailySched[s].StopTime < ApptViewCur.OnlySchedAfterTime)
                            {
                                continue;
                            }
                        }
                        if (ApptViewCur.OnlySchedBeforeTime > new TimeSpan(0, 0, 0))
                        {
                            if (dailySched[s].StartTime > ApptViewCur.OnlySchedBeforeTime ||
                                dailySched[s].StopTime > ApptViewCur.OnlySchedBeforeTime)
                            {
                                continue;
                            }
                        }
                        //this 'sched' must apply to this situation.
                        //listSchedOps is the ops for this 'sched'.
                        listSchedOps = dailySched[s].Ops;
                        //Add all the ops for this 'sched' to the list of visible ops
                        for (int p = 0; p < listSchedOps.Count; p++)
                        {
                            //Filter the ops if the clinic option was set for the appt view.
                            if (ApptViewCur.ClinicNum > 0 && ApptViewCur.ClinicNum != Operatories.GetOperatory(listSchedOps[p]).ClinicNum)
                            {
                                continue;
                            }
                            if (listSchedOps[p] == OperatoryC.ListShort[i].OperatoryNum)
                            {
                                Operatory op = OperatoryC.ListShort[i];
                                indexOp = Operatories.GetOrder(listSchedOps[p]);
                                if (indexOp != -1 && !ApptDrawing.VisOps.Contains(op))                               //prevents adding duplicate ops
                                {
                                    ApptDrawing.VisOps.Add(op);
                                    opAdded = true;
                                    break;
                                }
                            }
                        }
                        //If the provider is not scheduled to any op(s), add their default op(s).
                        if (OperatoryC.ListShort[i].ProvDentist == dailySched[s].ProvNum && listSchedOps.Count == 0)                     //only if the sched does not specify any ops
                        //Only add the op if the clinic option was not set in the appt view or if the op is assigned to that clinic.
                        {
                            if (ApptViewCur.ClinicNum == 0 || ApptViewCur.ClinicNum == OperatoryC.ListShort[i].ClinicNum)
                            {
                                indexOp = Operatories.GetOrder(OperatoryC.ListShort[i].OperatoryNum);
                                if (indexOp != -1 && !ApptDrawing.VisOps.Contains(OperatoryC.ListShort[i]))
                                {
                                    ApptDrawing.VisOps.Add(OperatoryC.ListShort[i]);
                                    opAdded = true;
                                }
                            }
                        }
                        if (opAdded)
                        {
                            break;                            //break out of the loop of schedules.  Continue with the next op.
                        }
                    }
                }
            }
            ApptDrawing.VisOps.Sort(CompareOps);
            ApptDrawing.VisProvs.Sort(CompareProvs);
        }
Ejemplo n.º 6
0
        private void FillGrid()
        {
            //do not refresh from db
            SchedList.Sort(CompareSchedule);
            graphScheduleDay.SetSchedules(SchedList);
            gridMain.BeginUpdate();
            gridMain.Columns.Clear();
            ODGridColumn col = new ODGridColumn(Lan.g("TableSchedDay", "Provider"), 100);

            gridMain.Columns.Add(col);
            col = new ODGridColumn(Lan.g("TableSchedDay", "Employee"), 100);
            gridMain.Columns.Add(col);
            col = new ODGridColumn(Lan.g("TableSchedDay", "Start Time"), 80);
            gridMain.Columns.Add(col);
            col = new ODGridColumn(Lan.g("TableSchedDay", "Stop Time"), 80);
            gridMain.Columns.Add(col);
            col = new ODGridColumn(Lan.g("TableSchedDay", "Ops"), 150);
            gridMain.Columns.Add(col);
            col = new ODGridColumn(Lan.g("TableSchedDay", "Note"), 100);
            gridMain.Columns.Add(col);
            gridMain.Rows.Clear();
            ODGridRow row;
            string    note;
            string    opdesc;

            //string opstr;
            //string[] oparray;
            for (int i = 0; i < SchedList.Count; i++)
            {
                row = new ODGridRow();
                //Prov
                if (SchedList[i].ProvNum != 0)
                {
                    row.Cells.Add(Providers.GetAbbr(SchedList[i].ProvNum));
                }
                else
                {
                    row.Cells.Add("");
                }
                //Employee
                if (SchedList[i].EmployeeNum == 0)
                {
                    row.Cells.Add("");
                }
                else
                {
                    row.Cells.Add(Employees.GetEmp(SchedList[i].EmployeeNum).FName);
                }
                //times
                if (SchedList[i].StartTime == TimeSpan.Zero &&
                    SchedList[i].StopTime == TimeSpan.Zero)
                //SchedList[i].SchedType==ScheduleType.Practice){
                {
                    row.Cells.Add("");
                    row.Cells.Add("");
                }
                else
                {
                    row.Cells.Add(SchedList[i].StartTime.ToShortTimeString());
                    row.Cells.Add(SchedList[i].StopTime.ToShortTimeString());
                }
                //ops
                opdesc = "";
                for (int o = 0; o < SchedList[i].Ops.Count; o++)
                {
                    Operatory op = Operatories.GetOperatory(SchedList[i].Ops[o]);
                    if (op.IsHidden)                     //Skip hidden operatories because it just confuses users.
                    {
                        continue;
                    }
                    if (opdesc != "")
                    {
                        opdesc += ",";
                    }
                    opdesc += op.Abbrev;
                }
                row.Cells.Add(opdesc);
                //note
                note = "";
                if (SchedList[i].Status == SchedStatus.Holiday)
                {
                    note += Lan.g(this, "Holiday: ");
                }
                note += SchedList[i].Note;
                row.Cells.Add(note);
                gridMain.Rows.Add(row);
            }
            gridMain.EndUpdate();
        }