Continuous Loop in PropertyChange Event !!!

Posts   
 
    
LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 15-Nov-2006 04:52:00   

I have an EmployeeEntity which has among others columns .... StatusTypeID (int) and Active (bit) fields. and I have StatusMasterEntity that has StatusTypeID (PK,int) and ImpliesActive (bit). As the user updates the status in a drop down the ImpliesActive needs to be updated in the Active field in the EmployeeEntity.

example StatusTypeID Description ImpliesActive 1 Active 1 2 Inactive 0 3 Fired 0 4 Prospect 1

i am Saving everything on the PropertyChange event (PropertyChange event is in Form, (presentation layer) and it passes the EmployeeEntity to my BLL for saving). So when the StatusTypeID gets changed in my "Trigger" (which is in BLL) i am updating Active field based on ImpliesActive from StatusMasterEntity. BUT when i update Active field it goes back to PropertyChange event and it is in a Continuous loop. I was wondering how others are handeling this type of situation, or if there is a better way.

Thanks

I am using Adapter, LLBL 2.0(oct 23rd), WinForm,.NET2.0, SQL2005.

Walaa avatar
Walaa
Support Team
Posts: 14951
Joined: 21-Aug-2005
# Posted on: 15-Nov-2006 06:52:33   

Please post the code of the PropertyChanged event handler.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39619
Joined: 17-Aug-2003
# Posted on: 15-Nov-2006 09:09:21   

Also: if this is an llblgen pro related support request, please post it in the proper forum. General chat isn't meant for issues you run into with llblgen pro, we've a set of other forums for that. simple_smile

Frans Bouma | Lead developer LLBLGen Pro
LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 15-Nov-2006 17:22:06   

Sorry, i will try to post in proper forum next time.

here is the code (this is not the actual code from my application, but similar which has the same issue).

i have a Form that has a checkbox to display active (bit), Two TextBox for FirstName, LastName and a combo for status. and a button to show the employee...here is how it starts... after form loads.



       // When the button is clicked, i am displaying the employee.

        private void button1_Click(object sender, EventArgs e)
        {
            ShowEmployee();
        }

        private void ShowEmployee()
        {
            DataAccessAdapter adapter = new DataAccessAdapter();
            employee = new EmployeeEntity(new System.Guid("685D3A76-D749-4A49-8C2A-512C67C83E68"));
            adapter.FetchEntity(employee);
            adapter.Dispose();
            BindData();
        }

        private void BindData()
        {
            RemoveBindings();
            textBox1.DataBindings.Add("Text", employee, "FirstName");
            textBox2.DataBindings.Add("Text", employee, "LastName");
            checkBox1.DataBindings.Add("Checked", employee, "Active");
            comboBox1.DataBindings.Add("Value", employee,"EmployeeStatusConfigChoiceID");
            DataIsBinded = true;
            employee.PropertyChanged += new PropertyChangedEventHandler(CurrentEmployee_PropertyChanged);

        }

        private void RemoveBindings()
        {
            if (DataIsBinded)
            {
                textBox1.DataBindings.RemoveAt(0);
                textBox2.DataBindings.RemoveAt(0);
                checkBox1.DataBindings.RemoveAt(0);
                comboBox1.DataBindings.RemoveAt(0);
            }
        }

        private void CurrentEmployee_PropertyChanged(object sender, EventArgs e)
        {
            SaveCurrentEmployee();
        }


        private void SaveCurrentEmployee()
        {
            if (employee.IsDirty)
            {
                if (employee.Fields["EmployeeStatusConfigChoiceID"].IsChanged)
                {

                   /*  from this part as soon as i update the  employee.Active  to something it again goes back to CurrentEmployee_PropertyChanged, which makes sence because the property changed again..but its not working...this will be in a continious loop and throws
"An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll"
*/

                    switch (comboBox1.Text)
                    {
                        case "Active":
                            employee.Active = true;
                            break;
                        case "Fired":
                            employee.Active = false;
                            break;
                        case "Prospect":
                            employee.Active = true;
                            break;
                        case "Inactive":
                            employee.Active = false;
                            break;
                    }
                }
                
                //it Never gets saved.

                DataAccessAdapter adapter = new DataAccessAdapter();
                adapter.SaveEntity(employee, true);
                ShowEmployee();
            }
        }


bclubb
User
Posts: 934
Joined: 12-Feb-2004
# Posted on: 16-Nov-2006 03:04:20   

It's a bit of a hack, but you could set a value that indicates that you are updating the field using the eventhandler and in this case you would not execute the update.

bool inHandler = false;
        private void SaveCurrentEmployee()
        {
            if(inHandler) return;
            inHandler = true;

            if (employee.IsDirty)
            {
                if (employee.Fields["EmployeeStatusConfigChoiceID"].IsChanged)
                {
                    

                 /* from this part as soon as i update the employee.Active to something it again goes back to CurrentEmployee_PropertyChanged, which makes sence because the property changed again..but its not working...this will be in a continious loop and throws
"An unhandled exception of type 'System.StackOverflowException' occurred in mscorlib.dll"
*/

                    switch (comboBox1.Text)
                    {
                        case "Active":
                            employee.Active = true;
                            break;
                        case "Fired":
                            employee.Active = false;
                            break;
                        case "Prospect":
                            employee.Active = true;
                            break;
                        case "Inactive":
                            employee.Active = false;
                            break;
                    }
                }
                
                //it Never gets saved.

                DataAccessAdapter adapter = new DataAccessAdapter();
                adapter.SaveEntity(employee, true);
                ShowEmployee();
                inHandler = false;
            }
        }


LLBLGen
User
Posts: 43
Joined: 10-Apr-2006
# Posted on: 16-Nov-2006 15:14:01   

I have actually tried that.

But here is the problem. Say I have to update 5 different things in different table in my trigger including the active bit field, if i flag it as if(inHandler) return; it works for the active field update, but as soon as it returns back to the trigger...............instead of hitting the other updates....for whatever reason it exits out of the "Trigger" and goes to the StatusEntity class, and the save never occurs.

I am surprised that no one has encountered this.

Now if i run the same save method with a button click event it works fine, this only is a problem inside the PropertyChanged event. And what is more surprising is instead of running my other updates in the “Trigger” it exits out directly to LLBL's generated code. I don’t know why it exits out of the "Trigger", but I think the reason why it goes to the StatusEntity is because all this originally happened during the status drop down change, which has the status EntityCollection as datasource. i say this because if i change the marital status of an Employee (which has MaritalStatus EntityCollection as datasource)..the trigger after updating the active goes to MaritalSatusEntity class.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39619
Joined: 17-Aug-2003
# Posted on: 17-Nov-2006 11:58:53   

PropertyChanged is raised for every property changed. So if 2 properties change, you get the event TWICE.

Also, it's raised every time a property changes. So if an FK is synced during a save, the property changed event is raised, which in your case likely triggers the save again.

I'm not sure if a propertychanged handler is the right place to save entities. Why do you want to persist an entity directly after a property has been changed? Why don't you wait for the user to confirm the change with a click on a Save button?

Frans Bouma | Lead developer LLBLGen Pro