Redundant Code?

Redundant Code?

Old forum URL: forums.lhotka.net/forums/t/660.aspx


DanEssin posted on Tuesday, July 18, 2006

I have had occasion to step throught the Csla code in the debugger many times while trying to understand how to get BO's configured properly. I have notices that in 2 areas (portal-related code) and validation-related code, the same blocks of code get executed over and over and over again. Last night I was stepping through some validation code and the validity of the each property of the BO was checked over 20 times in the course of calling Save().

This seems to be incredibly inefficient, but there is so much indirection involved in the code at these points that I am at a loss as to how to determine if this is the expected behavior or if something is not right with the code.

So far, with the 2 projects in which I have used Csla and actually put into production, I have had to go into the root BO's and rip out all of the Csla framework stuff and make the insert, update and delete methods public methods of the class in order to get decent execution speed and reliable behavior. The readonly lists, on the other hand, seem to work fine. This kind of defeats the point of using the framework in the first place.

Any help or suggestions would be appreciated.

RockfordLhotka replied on Tuesday, July 18, 2006

Normally CheckRules() should only be called from PropertyHasChanged(), which should only be called in your property set blocks.

During a Save() operation the properties shouldn't be getting set, so CheckRules() shouldn't trigger. If it is triggering, then you have something odd with either your UI or object (I am assuming you are using a local data portal).

If, by checking validity, you mean IDataErrorInfo methods are called, then that's a different matter. Those methods are called by data binding, and quite often. But if they are being called during your Save() call, then you are not properly disconnecting event handling at the bindingsource. This is discussed in the book - you need to turn off event handling at the bindingsource or things get ugly.

DanEssin replied on Tuesday, July 18, 2006

Thanks. The behavior that I have ended up with is probably the result of
trying to make sure that all of the controls that did not properly
notify the BO of their changes from the UI, got their changes applied
just before doing the save.

I've obviously got to resolve the UI notification failure as that is the
root of all this evil. I will look into turning off the event handling too.

btw, any suggestions on how best to get a control that isn't signaling
that it has been updated, to send a signal?

Thanks again,

RockfordLhotka wrote:
>
> Normally CheckRules() should only be called from PropertyHasChanged(),
> which should only be called in your property set blocks.
>
> During a Save() operation the properties shouldn't be getting set, so
> CheckRules() shouldn't trigger. If it is triggering, then you have
> something odd with either your UI or object (I am assuming you are
> using a local data portal).
>
> If, by checking validity, you mean IDataErrorInfo methods are called,
> then that's a different matter. Those methods are called by data
> binding, and quite often. But if they are being called during your
> Save() call, then you are not properly disconnecting event handling at
> the bindingsource. This is discussed in the book - you need to turn
> off event handling at the bindingsource or things get ugly.
>
>
>
>

RockfordLhotka replied on Tuesday, July 18, 2006

Are your combobox controls never updating the object? That's not right. I use comboboxes all the time and they update when you tab off the control (I just sometimes wish they did an update when I selected an item).

If this is the case, then you aren't binding to them correctly - at least that's been my experience.

I always use drag-and-drop binding now with comboboxes.

  1. Set the object property control type to combobox in the data sources window
  2. Drag the object (or property) onto the form to create the combobox
  3. THEN drag the namevaluelist object node from the data sources window onto the existing combobox control

It is like a magic incantation - all the data binding properties of the control get set up correctly. When I try to do it by hand I usually mess it up, so I've taken to just doing it this way all the time.

DanEssin replied on Tuesday, July 18, 2006

I've been doing it by hand. I'll try drag-and-drop.

Thanks,
de

On Tue, 18 Jul 2006 16:41:45 -0500, "RockfordLhotka"
said:
> Are your combobox controls never updating the object? That's not right. I
> use comboboxes all the time and they update when you tab off the control
> (I just sometimes wish they did an update when I selected an item).
>
> If this is the case, then you aren't binding to them correctly - at least
> that's been my experience.
>
> I always use drag-and-drop binding now with comboboxes.
>
> Set the object property control type to combobox in the data sources
> window
> Drag the object (or property) onto the form to create the combobox
> THEN drag the namevaluelist object node from the data sources window onto
> the existing combobox control
>
> It is like a magic incantation - all the data binding properties of the
> control get set up correctly. When I try to do it by hand I usually mess
> it up, so I've taken to just doing it this way all the time.
>
>

DanEssin replied on Tuesday, July 18, 2006

Using the drag-and-drop is the answer. It set a whole bunch of things
that I wouldn't have thought to do manually. Things are working more as
I would expect.

What can you tell me about OnUnknownPropertyChanged().
When I call CancelEdit, this particular method is taking over 30 seconds
to execute. the BO has about 60 fields. (and you're right, I'm running
local).

Thanks,
de

On Tue, 18 Jul 2006 16:41:45 -0500, "RockfordLhotka"
said:
> Are your combobox controls never updating the object? That's not right. I
> use comboboxes all the time and they update when you tab off the control
> (I just sometimes wish they did an update when I selected an item).
>
> If this is the case, then you aren't binding to them correctly - at least
> that's been my experience.
>
> I always use drag-and-drop binding now with comboboxes.
>
> Set the object property control type to combobox in the data sources
> window
> Drag the object (or property) onto the form to create the combobox
> THEN drag the namevaluelist object node from the data sources window onto
> the existing combobox control
>
> It is like a magic incantation - all the data binding properties of the
> control get set up correctly. When I try to do it by hand I usually mess
> it up, so I've taken to just doing it this way all the time.
>
>

RockfordLhotka replied on Tuesday, July 18, 2006

I discuss OnUnknownPropertyChanged() in the book, and not in entirely glowing terms. You can read up on it there, and why it is the way it is.

But for it to take 30 seconds with 60 fields seems quite amazing to me. It is certainly the case that it triggers data binding to do a refresh for each property on the object - which is not pleasant. Normally this is bad, but not THAT bad. My guess is that you've got some extra work occuring due to the data binding refresh, that really shouldn't happen in such a case.

The good news is that the method is Overridable/virtual, so you can replace it with a more efficient implementation for your particular object.

The thing is, all it REALLY needs to do is raise the PropertyChanged event for any single property that you KNOW is currently bound to a control. One general solution is to return to what I did in CSLA .NET 1.x, and raise PropertyChanged for the IsDirty property - then make sure to always, always, always bind a checkbox control to IsDirty on every form (and set the checkbox control's size to 0,0).

Another possibility, on a per-object basis, is to pick a property you know will always be bound to a visible, enabled control and raise PropertyChanged for that particular property. For instance, if you know that the Id property will always be bound on your forms, you could do this:

Protected Overrides Sub OnUnknownPropertyChanged()
  OnPropertyChanged("Id")
End Sub

The result is that data binding will refresh as needed - but just once, instead of once per property.

DanEssin replied on Wednesday, July 19, 2006

Thanks. I think I have a property that is a perfect candidate for the
override to signal on. I'll go to work on it. This project is really
starting to gel!

Thanks again,
de

RockfordLhotka wrote:

> I discuss OnUnknownPropertyChanged() in the book, and not in entirely
> glowing terms. You can read up on it there, and why it is the way it is.
>
> But for it to take 30 seconds with 60 fields seems quite amazing to
> me. It is certainly the case that it triggers data binding to do a
> refresh for each property on the object - which is not pleasant.
> Normally this is bad, but not THAT bad. My guess is that you've got
> some extra work occuring due to the data binding refresh, that really
> shouldn't happen in such a case.
>
> The good news is that the method is Overridable/virtual, so you can
> replace it with a more efficient implementation for your particular
> object.
>
> The thing is, all it REALLY needs to do is raise the PropertyChanged
> event for any single property that you KNOW is currently bound to a
> control. One general solution is to return to what I did in CSLA .NET
> 1.x, and raise PropertyChanged for the IsDirty property - then make
> sure to always, always, always bind a checkbox control to IsDirty on
> every form (and set the checkbox control's size to 0,0).
>
> Another possibility, on a per-object basis, is to pick a property you
> know will always be bound to a visible, enabled control and raise
> PropertyChanged for that particular property. For instance, if you
> know that the Id property will always be bound on your forms, you
> could do this:
>
> Protected Overrides Sub OnUnknownPropertyChanged()
> OnPropertyChanged("Id")
> End Sub
>
> The result is that data binding will refresh as needed - but just
> once, instead of once per property.
>
>
>
>

DanEssin replied on Wednesday, July 19, 2006

One more question about IsDirty. It doesn't show up as a property in the
data source so there is no way to drag it to a checkbox. I tried setting
the binding on the checkbox manually but I get an error "Cannot bind to
perperty IsDirty of the datasource."

Any pointers on how to make this work?

Thanks,
de

On Tue, 18 Jul 2006 19:44:46 -0500, "RockfordLhotka"
said:
> I discuss OnUnknownPropertyChanged() in the book, and not in entirely
> glowing terms. You can read up on it there, and why it is the way it is.
>
> But for it to take 30 seconds with 60 fields seems quite amazing to me.
> It is certainly the case that it triggers data binding to do a refresh
> for each property on the object - which is not pleasant. Normally this is
> bad, but not THAT bad. My guess is that you've got some extra work
> occuring due to the data binding refresh, that really shouldn't happen in
> such a case.
>
> The good news is that the method is Overridable/virtual, so you can
> replace it with a more efficient implementation for your particular
> object.
>
> The thing is, all it REALLY needs to do is raise the PropertyChanged
> event for any single property that you KNOW is currently bound to a
> control. One general solution is to return to what I did in CSLA .NET
> 1.x, and raise PropertyChanged for the IsDirty property - then make sure
> to always, always, always bind a checkbox control to IsDirty on every
> form (and set the checkbox control's size to 0,0).
>
> Another possibility, on a per-object basis, is to pick a property you
> know will always be bound to a visible, enabled control and raise
> PropertyChanged for that particular property. For instance, if you know
> that the Id property will always be bound on your forms, you could do
> this:
>
> Protected Overrides Sub OnUnknownPropertyChanged()
> OnPropertyChanged("Id")
> End Sub
>
> The result is that data binding will refresh as needed - but just once,
> instead of once per property.
>
>

ajj3085 replied on Thursday, July 20, 2006

Its marked with a Browsable( false ) attribute, so you can't use it for databinding.  One solution is to create your own property which just returns IsDirty, and bind do that.

RockfordLhotka replied on Thursday, July 20, 2006

It is just one line of code to do the binding - often placed in the form load event handler:
 
chkIsDirty.DataBindings.Add("Value", _customer, "IsDirty")
 
To make this really work, you need to be able to rebind as well - if you ever change the object to which the form is bound. In the previous edition of the books I'd created a helper function to handle the unbind-rebind code (because unbinding isn't so easy).
 
Rocky


From: ajj3085 [mailto:cslanet@lhotka.net]
Sent: Thursday, July 20, 2006 7:21 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Its marked with a Browsable( false ) attribute, so you can't use it for databinding.  One solution is to create your own property which just returns IsDirty, and bind do that.



DanEssin replied on Thursday, July 20, 2006

Thanks. I was trying to used "Checked" rather than value.

de

Rockford Lhotka wrote:
It is just one line of code to do the binding - often placed in the form load event handler:
 
chkIsDirty.DataBindings.Add("Value", _customer, "IsDirty")
 
To make this really work, you need to be able to rebind as well - if you ever change the object to which the form is bound. In the previous edition of the books I'd created a helper function to handle the unbind-rebind code (because unbinding isn't so easy).
 
Rocky


From: ajj3085 [mailto:cslanet@lhotka.net]
Sent: Thursday, July 20, 2006 7:21 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Its marked with a Browsable( false ) attribute, so you can't use it for databinding.  One solution is to create your own property which just returns IsDirty, and bind do that.






RockfordLhotka replied on Thursday, July 20, 2006

Well, Checked might be the right property - I typed this into Outlook, and so there was no Intellisense :)
 
Rocky


From: Daniel Essin [mailto:cslanet@lhotka.net]
Sent: Thursday, July 20, 2006 4:52 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Thanks. I was trying to used "Checked" rather than value.

de

Rockford Lhotka wrote:
It is just one line of code to do the binding - often placed in the form load event handler:
 
chkIsDirty.DataBindings.Add("Value", _customer, "IsDirty")
 
To make this really work, you need to be able to rebind as well - if you ever change the object to which the form is bound. In the previous edition of the books I'd created a helper function to handle the unbind-rebind code (because unbinding isn't so easy).
 
Rocky


From: ajj3085 [mailto:cslanet@lhotka.net]
Sent: Thursday, July 20, 2006 7:21 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Its marked with a Browsable( false ) attribute, so you can't use it for databinding.  One solution is to create your own property which just returns IsDirty, and bind do that.









DanEssin replied on Monday, July 24, 2006

Followup. I finally found something that worked.

I added the following to my class which made it appear in the datasources list of fields and I could then drop it onto the check box.

       [System.ComponentModel.Browsable(true)]
        public new bool IsDirty
        {
            get
            {
                return base.IsDirty;
            }
            //set
        }

I then added to the form:

       private void chkIsDirty_CheckedChanged(object sender, EventArgs e)
        {
            saveChangesToolStripMenuItem.Enabled = (chkIsDirty.Checked);
        }

I think that I may add the first snippet to my template and generate it into all of the instances. It seems useful. Your thoughts?

Thanks,
Dan

Rockford Lhotka wrote:
Well, Checked might be the right property - I typed this into Outlook, and so there was no Intellisense :)
 
Rocky


From: Daniel Essin [mailto:cslanet@lhotka.net]
Sent: Thursday, July 20, 2006 4:52 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Thanks. I was trying to used "Checked" rather than value.

de

Rockford Lhotka wrote:
It is just one line of code to do the binding - often placed in the form load event handler:
 
chkIsDirty.DataBindings.Add("Value", _customer, "IsDirty")
 
To make this really work, you need to be able to rebind as well - if you ever change the object to which the form is bound. In the previous edition of the books I'd created a helper function to handle the unbind-rebind code (because unbinding isn't so easy).
 
Rocky


From: ajj3085 [mailto:cslanet@lhotka.net]
Sent: Thursday, July 20, 2006 7:21 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Its marked with a Browsable( false ) attribute, so you can't use it for databinding.  One solution is to create your own property which just returns IsDirty, and bind do that.












DanEssin replied on Thursday, July 20, 2006

good suggestion.

Thanks,
de

ajj3085 wrote:
Its marked with a Browsable( false ) attribute, so you can't use it for databinding.  One solution is to create your own property which just returns IsDirty, and bind do that.



DanEssin replied on Monday, July 24, 2006

Question: Why does
protected void MarkClean()
{
_isDirty = false;
OnUnknownPropertyChanged();
}
call OnUnknownPropertyChanged(). Following your suggestion to override
it and raise OnPropertyChanged on a field that I know is bound and
visible, OnUnknownPropertyChanged raises OnPropertyChanged("MRN") which
sets _isDirty back to true - so the form never thinks that it is done
saving and it keeps prompting to save over and over.

I must have missed something.

Thanks,
de

RockfordLhotka wrote:
>
> I discuss OnUnknownPropertyChanged() in the book, and not in entirely
> glowing terms. You can read up on it there, and why it is the way it is.
>
> But for it to take 30 seconds with 60 fields seems quite amazing to
> me. It is certainly the case that it triggers data binding to do a
> refresh for each property on the object - which is not pleasant.
> Normally this is bad, but not THAT bad. My guess is that you've got
> some extra work occuring due to the data binding refresh, that really
> shouldn't happen in such a case.
>
> The good news is that the method is Overridable/virtual, so you can
> replace it with a more efficient implementation for your particular
> object.
>
> The thing is, all it REALLY needs to do is raise the PropertyChanged
> event for any single property that you KNOW is currently bound to a
> control. One general solution is to return to what I did in CSLA .NET
> 1.x, and raise PropertyChanged for the IsDirty property - then make
> sure to always, always, always bind a checkbox control to IsDirty on
> every form (and set the checkbox control's size to 0,0).
>
> Another possibility, on a per-object basis, is to pick a property you
> know will always be bound to a visible, enabled control and raise
> PropertyChanged for that particular property. For instance, if you
> know that the Id property will always be bound on your forms, you
> could do this:
>
> Protected Overrides Sub OnUnknownPropertyChanged()
> OnPropertyChanged("Id")
> End Sub
>
> The result is that data binding will refresh as needed - but just
> once, instead of once per property.
>
>
>
>

RockfordLhotka replied on Monday, July 24, 2006

Two things:

1. You probably don't want to call OnPropertyChanged, but rather just raise
the PropertyChanged event. I think I misspoke in a previous post on this
topic.

2. In this thread or another, there's been discussion about
OnUnknownPropertyChanged and how it works. Someone kindly pointed out that
if you raise PropertyChanged with a property name of "" or string.Empty data
binding will refresh all controls - which is really nice. So in 2.1 this is
what CSLA will do in its default OnUnknownPropertyChanged implementation.

What this means, is that you _should_ be able to raise PropertyChanged for
"" and all should be well.

Rocky

> -----Original Message--
> From: Daniel Essin [mailto:cslanet@lhotka.net]
> Sent: Monday, July 24, 2006 6:55 PM
> To: rocky@lhotka.net
> Subject: Re: [CSLA .NET] Redundant Code?
>
> Question: Why does
> protected void MarkClean()
> {
> _isDirty = false;
> OnUnknownPropertyChanged();
> }
> call OnUnknownPropertyChanged(). Following your suggestion to
> override it and raise OnPropertyChanged on a field that I
> know is bound and visible, OnUnknownPropertyChanged raises
> OnPropertyChanged("MRN") which sets _isDirty back to true -
> so the form never thinks that it is done saving and it keeps
> prompting to save over and over.
>
> I must have missed something.
>
> Thanks,
> de

DanEssin replied on Monday, July 24, 2006

Thanks. I'll try that.

Dan

Rockford Lhotka wrote:
Two things:

1. You probably don't want to call OnPropertyChanged, but rather just raise
the PropertyChanged event. I think I misspoke in a previous post on this
topic.

2. In this thread or another, there's been discussion about
OnUnknownPropertyChanged and how it works. Someone kindly pointed out that
if you raise PropertyChanged with a property name of "" or string.Empty data
binding will refresh all controls - which is really nice. So in 2.1 this is
what CSLA will do in its default OnUnknownPropertyChanged implementation.

What this means, is that you _should_ be able to raise PropertyChanged for
"" and all should be well.

Rocky

  
-----Original Message--
From: Daniel Essin [mailto:cslanet@lhotka.net] 
Sent: Monday, July 24, 2006 6:55 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Question: Why does
    protected void MarkClean()
    {
      _isDirty = false;
      OnUnknownPropertyChanged();
    }
call OnUnknownPropertyChanged(). Following your suggestion to 
override it and raise OnPropertyChanged on a field that I 
know is bound and visible, OnUnknownPropertyChanged raises 
OnPropertyChanged("MRN") which sets _isDirty back to true - 
so the form never thinks that it is done saving and it keeps 
prompting to save over and over.

I must have missed something.

Thanks,
de
    



  

DanEssin replied on Tuesday, July 25, 2006

Rocky,

I'm getting really confused but I think the problem originates with the way data binding works. Here's my scenario. A user changes data in a field on an mdi child form and then clicks a menu item on the mdi parent form to change to a different function of the app. I want to detect and warn the user if their changes have not been saved. Regardless of how much fiddling I do with PropertyHasChanged or IsDirty, if the user has not caused the focus to shift to another field of the form that they are currently on, the IsDirty property never gets set. On the other hand, if I override UnknownPropertyHas changed and raise PropertyHasChanged("") then the BO never gest marked as clean (i.e. it keeps testing dirty no matter how many times applyedit and save are invoked

It seem to be a no-win situation. The only thing that I have come up with that works is the following:
        public void PostData()
        {
            try
            {
                int marker = this.tabControl1.SelectedIndex;
                this.tabControl1.SelectedIndex = 0;
                this.chkIsDirty.Focus();
                this.tabControl1.SelectedIndex = marker;

            }
            catch (Exception ex)
            {
                ((MainForm)MdiParent).StatusMessage = ex.Message;
            }
        }

        public void SaveData()
        {
            try
            {
                if (_call.IsDirty)
                {
                    _call.ApplyEdit();
                    _call.Save();
                    ((MainForm)MdiParent).StatusMessage = "Record Saved";
                }

            }
            catch (Exception ex)
            {
                ((MainForm)MdiParent).StatusMessage = ex.Message;
            }
        }

        private void FormPhoneCall_FormClosing(object sender, FormClosingEventArgs e)
        {
            PostData();
            if (_call.IsDirty)
            {
                if (MessageBox.Show("Save Changes?", "Data Changed", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    SaveData();
                }
            }
        }


PostData() gets called at every point where I want to test IsDirty, before actually testing it.

I have also added the following to my business object:
        protected override void OnUnknownPropertyChanged()
        {
            base.OnUnknownPropertyChanged();
            //PropertyHasChanged("");
        }

        [System.ComponentModel.Browsable(true)]
        public new bool IsDirty
        {
            get
            {
                return base.IsDirty;
            }
            //set
        }

and this IsDirty is bound to chkIsDirty with 0,0 size that is on the form.

I have a feeling that I've totally perverted what you originally had in mind. What am I missing?


Thanks,
Dan

Rockford Lhotka wrote:
Two things:

1. You probably don't want to call OnPropertyChanged, but rather just raise
the PropertyChanged event. I think I misspoke in a previous post on this
topic.

2. In this thread or another, there's been discussion about
OnUnknownPropertyChanged and how it works. Someone kindly pointed out that
if you raise PropertyChanged with a property name of "" or string.Empty data
binding will refresh all controls - which is really nice. So in 2.1 this is
what CSLA will do in its default OnUnknownPropertyChanged implementation.

What this means, is that you _should_ be able to raise PropertyChanged for
"" and all should be well.

Rocky

  
-----Original Message--
From: Daniel Essin [mailto:cslanet@lhotka.net] 
Sent: Monday, July 24, 2006 6:55 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Question: Why does
    protected void MarkClean()
    {
      _isDirty = false;
      OnUnknownPropertyChanged();
    }
call OnUnknownPropertyChanged(). Following your suggestion to 
override it and raise OnPropertyChanged on a field that I 
know is bound and visible, OnUnknownPropertyChanged raises 
OnPropertyChanged("MRN") which sets _isDirty back to true - 
so the form never thinks that it is done saving and it keeps 
prompting to save over and over.

I must have missed something.

Thanks,
de
    



  

tetranz replied on Thursday, July 27, 2006

Just catching up on some reading from a few days ago ...
RockfordLhotka:
Are your combobox controls never updating the object? That's not right. I use comboboxes all the time and they update when you tab off the control (I just sometimes wish they did an update when I selected an item).
If you want a control to update instantly, edit its DataBindings / Advanced properties and change the data source update mode for that binding from OnValidation to OnPropertyChanged. It works great for discreet value type controls like checkboxes, dropdown lists etc. Probably not the best thing to do with a textbox because it would fire away on every keystroke.

Ross

DanEssin replied on Thursday, July 27, 2006

Thanks, that's extremely helpful. I didn't know about that property
before. I will definitely try it.

de

On Thu, 27 Jul 2006 15:57:52 -0500, "tetranz" said:
> Just catching up on some reading from a few days ago ...
> RockfordLhotka:Are your combobox controls never updating the object?
> That's not right. I use comboboxes all the time and they update when you
> tab off the control (I just sometimes wish they did an update when I
> selected an item).If you want a control to update instantly, edit its
> DataBindings / Advanced properties and change the data source update mode
> for that binding from OnValidation to OnPropertyChanged. It works great
> for discreet value type controls like checkboxes, dropdown lists etc.
> Probably not the best thing to do with a textbox because it would fire
> away on every keystroke.
>
> Ross
>
>
>

DanEssin replied on Tuesday, July 25, 2006

That call to OnUnknownPropertyChanged() really does take between 30 and
45 seconds to get to the DataPortal_Update method.

This is the structure of the BO:

//declare members
private Guid _EncId = Guid.NewGuid();
private string _MRN = string.Empty;
private string _ENCTYPE = string.Empty;
private string _CALLERNAME = string.Empty;
private string _CALLERPHONENUM = string.Empty;
private string _PROVIDERONCALL = string.Empty;
private SmartDate _CALLDATE = new SmartDate(true);
private int _AFTERHOURS = 0;
private string _PTADDR1 = string.Empty;
private string _PTADDR2 = string.Empty;
private string _PTCITY = string.Empty;
private string _PTZIP = string.Empty;
private string _PTPHONENUM = string.Empty;
private string _PRIMARYCARESITE = string.Empty;
private string _COVERAGE = string.Empty;
private string _CALLEDFROM = string.Empty;
private string _CALLINGPROVIDER = string.Empty;
private string _CALLERADDRESS1 = string.Empty;
private string _CALLERADDRESS2 = string.Empty;
private string _CALLERCITY = string.Empty;
private string _CALLERSTATE = string.Empty;
private string _CALLERZIP = string.Empty;
private string _CHIEFCOMPLAINT = string.Empty;
private string _TEMPERATURE = string.Empty;
private string _PULSE = string.Empty;
private string _RESP = string.Empty;
private string _BP = string.Empty;
private string _ALLERGIES = string.Empty;
private int _NEWPROBLEM = 0;
private string _PROBLEMDURATION = string.Empty;
private string _PROBUNITS = string.Empty;
private string _PASTMEDHX = string.Empty;
private string _MEDICATIONS = string.Empty;
private string _WORKINGDX = string.Empty;
private string _ICD9 = string.Empty;
private string _NOTES = string.Empty;
private string _ADVICEGIVEN = string.Empty;
private string _DISPO = string.Empty;
private string _REFERRALTYPE = string.Empty;
private string _INPATIENTSITE = string.Empty;
private string _URGENTCARESITE = string.Empty;
private string _EXTERNALSITE = string.Empty;
private string _AUTHACTION = string.Empty;
private string _AUTHNUM = string.Empty;
private string _AUTHLOS = string.Empty;
private string _TRANSPORTATION = string.Empty;
private SmartDate _CmNotifydate = new SmartDate(true);
private int _NEEDSFU = 0;
private string _FuNotes = string.Empty;
private SmartDate _CHPADMINDATE = new SmartDate(true);
private SmartDate _PCSDATE = new SmartDate(true);
private SmartDate _CREATEDATE = new SmartDate(true);
private string _ORIGINALMRN = string.Empty;
private string _UmOperator = string.Empty;
private SmartDate _TimeMdCalled = new SmartDate(true);
private SmartDate _TimeMdResp = new SmartDate(true);
private string _CALLINGPROVIDERPHONE = string.Empty;

As I mentioned before, leaving the call to OnUnknownPropertyChanged() in
has the side effect of either resetting or not clearing the IsDirty flag.

RockfordLhotka replied on Tuesday, July 25, 2006

DanEssin:
As I mentioned before, leaving the call to OnUnknownPropertyChanged() in has the side effect of either resetting or not clearing the IsDirty flag.

And this is what has me concerned. This call shouldn't be altering IsDirty at all. Only the MarkDirty() and MarkClean() methods alter the value of IsDirty. Neither of these methods are called as part of OnPropertyChanged() or OnUnknownPropertyChanged(), and so something else is obviously triggering a call to one or both of these methods. That's suspicious, as it implies that there's some other processing going on here outside of CSLA itself.

When in doubt, always fall back to a simple example and troubleshoot. I'm attaching a simple example that doesn't seem to have your issue, and which illustrates how the binding should work. There's something different in your code that's causing your IsDirty issue.

RockfordLhotka replied on Tuesday, July 25, 2006

Sorry, forgot the Cancel button. It is just another button, with the following code:

Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click

    Me.PersonBindingSource.CancelEdit()

End Sub

DanEssin replied on Tuesday, July 25, 2006

Did I miss something? You mentioned an attachment but I can't find it.

Thanks,
Dan

RockfordLhotka wrote:
DanEssin:
As I mentioned before, leaving the call to OnUnknownPropertyChanged() in has the side effect of either resetting or not clearing the IsDirty flag.

And this is what has me concerned. This call shouldn't be altering IsDirty at all. Only the MarkDirty() and MarkClean() methods alter the value of IsDirty. Neither of these methods are called as part of OnPropertyChanged() or OnUnknownPropertyChanged(), and so something else is obviously triggering a call to one or both of these methods. That's suspicious, as it implies that there's some other processing going on here outside of CSLA itself.

When in doubt, always fall back to a simple example and troubleshoot. I'm attaching a simple example that doesn't seem to have your issue, and which illustrates how the binding should work. There's something different in your code that's causing your IsDirty issue.




RockfordLhotka replied on Tuesday, July 25, 2006

If you are doing this via email you'll need to go to the forum itself to get the attachment. It appears as a link in the header of that particular post.
 
Rocky


From: Daniel Essin [mailto:cslanet@lhotka.net]
Sent: Tuesday, July 25, 2006 5:24 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Did I miss something? You mentioned an attachment but I can't find it.

Thanks,
Dan

DanEssin replied on Tuesday, July 25, 2006

duhh...
It's on page 2 (of course)
Thanks,
Dan

Rockford Lhotka wrote:
If you are doing this via email you'll need to go to the forum itself to get the attachment. It appears as a link in the header of that particular post.
 
Rocky


From: Daniel Essin [mailto:cslanet@lhotka.net]
Sent: Tuesday, July 25, 2006 5:24 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Did I miss something? You mentioned an attachment but I can't find it.

Thanks,
Dan



DanEssin replied on Wednesday, July 26, 2006

Yeah, my oversight. I didn't notice that there was a page 2.

I've got a couple more questions about the OnUnknownPropertyChanged and the sample.

1 - The sample didn't actually compile until I added an inner Criteria class to person and pass a new instance to the Fetch.

2 - In your sample, OnUnknownPropertyChanged() is called 9 times

2 - When I run the sample it calls OnUnknownPropertyChanged() once and executes instantaneously. When I call _call.Save() in my app, it calls OnUnknownPropertyChanged() twice and each call takes 65-70 seconds to execute. If I comment out the call to OnUnknownPropertyChanged(), everything still saves OK.

I have also noted the following. This code from BusinessBase:
    public override bool Equals(object obj)
    {
      if (obj is T)
      {
        object id = GetIdValue();
        if (id == null)
          throw new ArgumentException(Resources.GetIdValueCantBeNull);
        return ((T)obj).GetIdValue().Equals(id);
      }
      else
        return false;
    }
 is being executed 71 times, once for each property of my BO and each time it has to do 2 calls to obj.GetID.

Also in your example nonSerializableHandlers is null. In my project this is not null and it calls:
        nonSerializableHandlers.Invoke(this,
          new PropertyChangedEventArgs(propertyName));
71 times. Each of these calls seems to visit more than one property of the BO so the net effect is that there are several hundred visits to properties of the bo for each call to OnUnknownPropertyChanged().

Then for some reason, the whole sequence repeats a second time before completing the call to Save().


 so that leaves a couple of questions:

a) When is it absolutely essential? (It will be called routinely unless I override it in the BO and suppress the call to base.OnUnknownPropertyChanged(), which I have done in this case. )

b) It seems like the verification of the object identity could be done only once per save rather than once perproperty?

c) Any idea on how to track down why each property is being visited so many times?

One final thing. I really think that the IsDirty on BusinessBase should be made browsable so that you could bind to it in a form. Doing this seems to help alot. I've made that change in the source for now.

Any ideas?

Thanks, Dan

Rockford Lhotka wrote:
If you are doing this via email you'll need to go to the forum itself to get the attachment. It appears as a link in the header of that particular post.
 
Rocky


From: Daniel Essin [mailto:cslanet@lhotka.net]
Sent: Tuesday, July 25, 2006 5:24 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] Redundant Code?

Did I miss something? You mentioned an attachment but I can't find it.

Thanks,
Dan



RockfordLhotka replied on Wednesday, July 26, 2006

Are you running 2.0.3? Or at least 2.0.2? In that case my code should run just fine without the need for a criteria class.


1 - The sample didn't actually compile until I added an inner Criteria class to person and pass a new instance to the Fetch.
 [...] 
c) Any idea on how to track down why each property is being visited so many times?

One final thing. I really think that the IsDirty on BusinessBase should be made browsable so that you could bind to it in a form. Doing this seems to help alot. I've made that change in the source for now.

 
Yes, I know exactly why many of these methods are called so many times - this is the way data binding works. If this is unacceptable, then don't use data binding. Other people have, in the past, found data binding to not meet their needs, and they've written their own replacements - and you may need to do the same thing.
 
However, I return to the fact that your IsDirty flag is somehow being set based on a PropertyChanged event being raised - and I again point out that you have something in your app that is doing this - it is not CSLA code by itself. Given that this is happening, no other results can be considered reliable, because we don't know (and you don't either) what code is running to cause this, and how long that code might take, etc.
 
In another thread it has been found that cascading ListChanged from a child collection up through the parent as PropertyChanged is highly problematic. I don't know if you are doing this, but at this point it is a highly suspect thing to do. Certainly the DataSet doesn't do this, and it appears that data binding just can't handle such an approach.
 
I have also updated my article on binding to IsDirty (and IsSavable, etc.), to specifically recommend the use of a bindingsource event rather than data binding when dealing with these top-level properties
 
http://www.lhotka.net/Article.aspx?area=4&id=5faaee8e-8496-4845-86f7-787c6b64096c
 
This is largely based on that other thread dealing with cacading events through parent objects - but it may matter here as well.
 
Rocky
 

RockfordLhotka replied on Wednesday, July 26, 2006

Sorry if the tone of my previous post seems abrupt. That was not my intent.

However, the point is this: you are encountering an issue that I have not seen in other apps, and which hasn't come up with the hundreds of other apps built by people using the framework.

Part of the issue is simply the way data binding works - it is very chatty with its data source.

But it seems quite clear that part of the issue must lie with your code. Since other appliations don't have these explosions of event processing, and don't have IsDirty getting changed mysteriously, the problem would appear to be unique to your situation - and thus to your code.

I strongly suggest stripping back your code to the simplest possible example and building forward from there. At some point you'll add in some feature that exists in your current app and the problem will appear, and then you'll know what change causes the issue.

DanEssin replied on Thursday, July 27, 2006

I didn't take your response as abrupt. I have a long history of finding creative ways to break things that are supposed to be bullet proof. This goes back to finding bugs in the A/D conversion assembly routines on the PDP-11,  having 5 of 5 crts shipped to me fail within the first year back in 1980, having Perter Norton tell me in 1981 that he didn't know that you could use Word to edit exe's that had ASCII drive letters embedded in the binaries to get them to use a different default drive, to finding over a dozen problems with the early releases of StrataFrame (a commercial BO framework that was released in 12/2005). Sometimes I just break things for stupid reasons because I am working in areas that I am still learning about and just plain violate the rules.

In any case, the version I was running is csla20cs-RTM-060321.zip. I will go get the latest one and I will take your suggestion about stripping it down.

The reason the IsDirty is getting reset when I put the PropertyHasChanged("") in the overridden OnUnknownPropertyChanged() is this:
    protected virtual void PropertyHasChanged(string propertyName)
    {
      ValidationRules.CheckRules(propertyName);
      MarkDirty(true);
      OnPropertyChanged(propertyName);
    }

----
At this point I've installed the latest 2.0.3 and striped the app down to a minimum. Here's a trace of what happens when it loads a record, processes on changed field and then does a save.
This is the code for the save:
        public void SaveData()
        {
            try
            {
                if (_call.IsDirty)
                {
                    Console.WriteLine("EndEdit");
                    bindingSourceCall.EndEdit();
                    Console.WriteLine("Save");
                    _call.Save();
                    Console.WriteLine("Done with Save");
                    ((MainForm)MdiParent).StatusMessage = "Record Saved";
                    this.bindingSourceCall.ResetBindings(false);
                }
            }
            catch (Exception ex)
            {
                ((MainForm)MdiParent).StatusMessage = ex.Message;
            }
        }

This is the trace (I've embedded a few comments):
Load an existing record--
BusinessBase.MarkOld()
BusinessBase.MarkClean()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
BindableBase.OnUnknownPropertyChanged()
BindableBase.OnPropertyChanged()EncId
BindableBase.OnPropertyChanged()MRN
BindableBase.OnPropertyChanged()ENCTYPE
BindableBase.OnPropertyChanged()CALLERNAME
BindableBase.OnPropertyChanged()CALLERPHONENUM
BindableBase.OnPropertyChanged()PROVIDERONCALL
BindableBase.OnPropertyChanged()CALLDATE
BindableBase.OnPropertyChanged()CALLDATEString
BindableBase.OnPropertyChanged()AFTERHOURS
BindableBase.OnPropertyChanged()PTADDR1
BindableBase.OnPropertyChanged()PTADDR2
BindableBase.OnPropertyChanged()PTCITY
BindableBase.OnPropertyChanged()PTZIP
BindableBase.OnPropertyChanged()PTPHONENUM
BindableBase.OnPropertyChanged()PRIMARYCARESITE
BindableBase.OnPropertyChanged()COVERAGE
BindableBase.OnPropertyChanged()CALLEDFROM
BindableBase.OnPropertyChanged()CALLINGPROVIDER
BindableBase.OnPropertyChanged()CALLERADDRESS1
BindableBase.OnPropertyChanged()CALLERADDRESS2
BindableBase.OnPropertyChanged()CALLERCITY
BindableBase.OnPropertyChanged()CALLERSTATE
BindableBase.OnPropertyChanged()CALLERZIP
BindableBase.OnPropertyChanged()CHIEFCOMPLAINT
BindableBase.OnPropertyChanged()TEMPERATURE
BindableBase.OnPropertyChanged()PULSE
BindableBase.OnPropertyChanged()RESP
BindableBase.OnPropertyChanged()BP
BindableBase.OnPropertyChanged()ALLERGIES
BindableBase.OnPropertyChanged()NEWPROBLEM
BindableBase.OnPropertyChanged()PROBLEMDURATION
BindableBase.OnPropertyChanged()PROBUNITS
BindableBase.OnPropertyChanged()PASTMEDHX
BindableBase.OnPropertyChanged()MEDICATIONS
BindableBase.OnPropertyChanged()WORKINGDX
BindableBase.OnPropertyChanged()ICD9
BindableBase.OnPropertyChanged()NOTES
BindableBase.OnPropertyChanged()ADVICEGIVEN
BindableBase.OnPropertyChanged()DISPO
BindableBase.OnPropertyChanged()REFERRALTYPE
BindableBase.OnPropertyChanged()INPATIENTSITE
BindableBase.OnPropertyChanged()URGENTCARESITE
BindableBase.OnPropertyChanged()EXTERNALSITE
BindableBase.OnPropertyChanged()AUTHACTION
BindableBase.OnPropertyChanged()AUTHNUM
BindableBase.OnPropertyChanged()AUTHLOS
BindableBase.OnPropertyChanged()TRANSPORTATION
BindableBase.OnPropertyChanged()CmNotifydate
BindableBase.OnPropertyChanged()CmNotifydateString
BindableBase.OnPropertyChanged()NEEDSFU
BindableBase.OnPropertyChanged()FuNotes
BindableBase.OnPropertyChanged()CHPADMINDATE
BindableBase.OnPropertyChanged()CHPADMINDATEString
BindableBase.OnPropertyChanged()PCSDATE
BindableBase.OnPropertyChanged()PCSDATEString
BindableBase.OnPropertyChanged()CREATEDATE
BindableBase.OnPropertyChanged()CREATEDATEString
BindableBase.OnPropertyChanged()ORIGINALMRN
BindableBase.OnPropertyChanged()UmOperator
BindableBase.OnPropertyChanged()TimeMdCalled
BindableBase.OnPropertyChanged()TimeMdCalledString
BindableBase.OnPropertyChanged()TimeMdResp
BindableBase.OnPropertyChanged()TimeMdRespString
BindableBase.OnPropertyChanged()CALLINGPROVIDERPHONE
BindableBase.OnPropertyChanged()IsNew
BindableBase.OnPropertyChanged()IsDeleted
BindableBase.OnPropertyChanged()IsDirty
BindableBase.OnPropertyChanged()IsSavable
BindableBase.OnPropertyChanged()IsValid
BindableBase.OnPropertyChanged()BrokenRulesCollection
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()

Edit 1 field--

BindableBase.OnPropertyChanged()CALLINGPROVIDER
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()

Call the SaveData() routine--

EndEdit()
Save()
SimpleDataPortal.Update()
BusinessBase.MarkClean()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
BindableBase.OnUnknownPropertyChanged()
BindableBase.OnPropertyChanged()EncId       // each one of these field events takes about 1 second and there are
PhoneCall.GetIdValue()                      // 71 of them.
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()MRN
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ENCTYPE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERNAME
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERPHONENUM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PROVIDERONCALL
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AFTERHOURS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTADDR1
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTADDR2
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTCITY
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTZIP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTPHONENUM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PRIMARYCARESITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()COVERAGE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLEDFROM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLINGPROVIDER
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERADDRESS1
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERADDRESS2
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERCITY
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERSTATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERZIP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CHIEFCOMPLAINT
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TEMPERATURE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PULSE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()RESP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()BP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ALLERGIES
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()NEWPROBLEM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PROBLEMDURATION
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PROBUNITS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PASTMEDHX
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()MEDICATIONS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()WORKINGDX
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ICD9
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()NOTES
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ADVICEGIVEN
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()DISPO
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()REFERRALTYPE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()INPATIENTSITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()URGENTCARESITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()EXTERNALSITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AUTHACTION
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AUTHNUM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AUTHLOS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TRANSPORTATION
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CmNotifydate
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CmNotifydateString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()NEEDSFU
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()FuNotes
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CHPADMINDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CHPADMINDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PCSDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PCSDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CREATEDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CREATEDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ORIGINALMRN
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()UmOperator
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdCalled
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdCalledString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdResp
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdRespString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLINGPROVIDERPHONE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsNew
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsDeleted
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsDirty
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsSavable
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsValid
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()BrokenRulesCollection
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
BusinessBase.MarkOld()                           // Why it does this whole thing a second time after the MarkOld()
BusinessBase.MarkClean()                         // I have no idea? but it takes another 70 seconds
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
BindableBase.OnUnknownPropertyChanged()
BindableBase.OnPropertyChanged()EncId
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()MRN
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ENCTYPE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERNAME
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERPHONENUM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PROVIDERONCALL
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AFTERHOURS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTADDR1
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTADDR2
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTCITY
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTZIP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PTPHONENUM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PRIMARYCARESITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()COVERAGE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLEDFROM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLINGPROVIDER
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERADDRESS1
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERADDRESS2
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERCITY
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERSTATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLERZIP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CHIEFCOMPLAINT
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TEMPERATURE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PULSE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()RESP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()BP
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ALLERGIES
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()NEWPROBLEM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PROBLEMDURATION
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PROBUNITS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PASTMEDHX
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()MEDICATIONS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()WORKINGDX
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ICD9
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()NOTES
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ADVICEGIVEN
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()DISPO
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()REFERRALTYPE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()INPATIENTSITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()URGENTCARESITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()EXTERNALSITE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AUTHACTION
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AUTHNUM
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()AUTHLOS
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TRANSPORTATION
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CmNotifydate
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CmNotifydateString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()NEEDSFU
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()FuNotes
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CHPADMINDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CHPADMINDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PCSDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()PCSDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CREATEDATE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CREATEDATEString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()ORIGINALMRN
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()UmOperator
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdCalled
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdCalledString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdResp
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()TimeMdRespString
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()CALLINGPROVIDERPHONE
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsNew
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsDeleted
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsDirty
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsSavable
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()IsValid
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
BindableBase.OnPropertyChanged()BrokenRulesCollection
PhoneCall.GetIdValue()
BusinessBase.Equals
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
Done with Save



RockfordLhotka wrote:

Sorry if the tone of my previous post seems abrupt. That was not my intent.

However, the point is this: you are encountering an issue that I have not seen in other apps, and which hasn't come up with the hundreds of other apps built by people using the framework.

Part of the issue is simply the way data binding works - it is very chatty with its data source.

But it seems quite clear that part of the issue must lie with your code. Since other appliations don't have these explosions of event processing, and don't have IsDirty getting changed mysteriously, the problem would appear to be unique to your situation - and thus to your code.

I strongly suggest stripping back your code to the simplest possible example and building forward from there. At some point you'll add in some feature that exists in your current app and the problem will appear, and then you'll know what change causes the issue.




RockfordLhotka replied on Thursday, July 27, 2006

 

The reason the IsDirty is getting reset when I put the PropertyHasChanged("") in the overridden OnUnknownPropertyChanged() is this:
    protected virtual void PropertyHasChanged(string propertyName)
    {
      ValidationRules.CheckRules(propertyName);
      MarkDirty(true);
      OnPropertyChanged(propertyName);
    }
 
But PropertyHasChanged() is only called in a property set block. OnUnknownPropertyChanged() triggers the raising of PropertyChanged event(s) and does NOT trigger calling any set blocks - only get blocks. Yes, data binding is very chatty, in that it reads values a lot. But it doesn't set them unless your UI code or the user sets them.
 
If PropertyHasChanged() is being called, it is because you have code somewhere that is setting one or more properties when a PropertyChanged event is handled.
 
Rocky

DanEssin replied on Thursday, July 27, 2006

I'm really trying hard to understand this stuff but I am baffled. I wish that you would look at this trace. The background is that an existing record has been retrieved into the BO and bound to the form and one text field has been edited. There is NO code that manipulates the BO other than the EndEdit and the Save.

The trace begins at the point where the Save menu is clicked. I don't know how to tell what is contained within _nonSerializableHandlers but
      if (nonSerializableHandlers != null)
        nonSerializableHandlers.Invoke(this,
          new PropertyChangedEventArgs(propertyName));
seems to be the origin of all the activity but I have not been able to discover why these fields are referenced over and over in every Invoke.

Save Menu Clicked
EndEdit()
Save()
SimpleDataPortal.Update()
BusinessBase.MarkOld()
BusinessBase.MarkClean()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
BindableBase.OnUnknownPropertyChanged()
BindableBase.OnPropertyChanged()EncId
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()MRN
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()ENCTYPE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
The thread '<No Name>' (0x118) has exited with code 0 (0x0).
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERNAME
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERPHONENUM
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PROVIDERONCALL
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLDATE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLDATEString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()AFTERHOURS
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PTADDR1
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PTADDR2
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PTCITY
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PTZIP
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PTPHONENUM
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PRIMARYCARESITE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()COVERAGE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLEDFROM
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLINGPROVIDER
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERADDRESS1
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERADDRESS2
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERCITY
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERSTATE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLERZIP
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CHIEFCOMPLAINT
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()TEMPERATURE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PULSE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()RESP
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()BP
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()ALLERGIES
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()NEWPROBLEM
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PROBLEMDURATION
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PROBUNITS
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PASTMEDHX
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()MEDICATIONS
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()WORKINGDX
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()ICD9
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()NOTES
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()ADVICEGIVEN
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()DISPO
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()REFERRALTYPE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()INPATIENTSITE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()URGENTCARESITE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()EXTERNALSITE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()AUTHACTION
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()AUTHNUM
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()AUTHLOS
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()TRANSPORTATION
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CmNotifydate
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CmNotifydateString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()NEEDSFU
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()FuNotes
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CHPADMINDATE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CHPADMINDATEString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PCSDATE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()PCSDATEString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CREATEDATE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CREATEDATEString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()ORIGINALMRN
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()UmOperator
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()TimeMdCalled
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()TimeMdCalledString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()TimeMdResp
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()TimeMdRespString
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()CALLINGPROVIDERPHONE
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()IsNew
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()IsDeleted
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()IsDirty
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()IsSavable
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()IsValid
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
BindableBase.OnPropertyChanged()BrokenRulesCollection
BusinessBase.Equals
PhoneCall.GetIdValue()
IDataErrorInfo.this CALLDATEString
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this AFTERHOURS
IDataErrorInfo.this UmOperator
IDataErrorInfo.this MRN
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLEDFROM
IDataErrorInfo.this CALLINGPROVIDERPHONE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this COVERAGE
IDataErrorInfo.this CALLINGPROVIDER
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PRIMARYCARESITE
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this PROVIDERONCALL
IDataErrorInfo.this CALLERPHONENUM
IDataErrorInfo.this CALLERNAME
IDataErrorInfo.this ENCTYPE
IDataErrorInfo.this ENCTYPE
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
PhoneCall.GetIdValue()
Done with Save


Rockford Lhotka wrote:
 

The reason the IsDirty is getting reset when I put the PropertyHasChanged("") in the overridden OnUnknownPropertyChanged() is this:
    protected virtual void PropertyHasChanged(string propertyName)
    {
      ValidationRules.CheckRules(propertyName);
      MarkDirty(true);
      OnPropertyChanged(propertyName);
    }
 
But PropertyHasChanged() is only called in a property set block. OnUnknownPropertyChanged() triggers the raising of PropertyChanged event(s) and does NOT trigger calling any set blocks - only get blocks. Yes, data binding is very chatty, in that it reads values a lot. But it doesn't set them unless your UI code or the user sets them.
 
If PropertyHasChanged() is being called, it is because you have code somewhere that is setting one or more properties when a PropertyChanged event is handled.
 
Rocky



Brian Criswell replied on Thursday, July 27, 2006

It looks like the problem is that you overrode OnUnknownPropertyChanged incorrectly.  If you look at the beginning of your stack trace, it calls MarkOld() which calls MarkClean() which calls OnUnknownPropertyChanged.  Your implementation is then calling PropertyHasChanged(string.Empty).  This goes right back to marking the whole thing as dirty again.  What happens if you override OnUnknownPropertyChanged to just call OnPropertyChanged(string.Empty)?  Your stack trace should quiet down after that, but I imagine that it will still be a bit chatty.

DanEssin replied on Thursday, July 27, 2006

Thanks, but I stripped all of that out before generating the last trace.

On Thu, 27 Jul 2006 15:33:33 -0500, "Brian Criswell"
said:
> It looks like the problem is that you overrode OnUnknownPropertyChanged
> incorrectly. If you look at the beginning of your stack trace, it calls
> MarkOld() which calls MarkClean() which calls OnUnknownPropertyChanged.
> Your implementation is then calling PropertyHasChanged(string.Empty).
> This goes right back to marking the whole thing as dirty again. What
> happens if you override OnUnknownPropertyChanged to just call
> OnPropertyChanged(string.Empty)? Your stack trace should quiet down
> after that, but I imagine that it will still be a bit chatty.
>
>
>

DanEssin replied on Thursday, July 27, 2006

I did some more testing of your sample with a completely virgin
installation of 2.0.3.
I have noted the same "malfunction". The Forms
propertyChangedEventHandler gets inserted into the
NonSerializableEventHandlers property of the BO twice and whenever there
is a data change in the form the PropertyChanged event is raised twice
on each field of the BO and it keeps gouing around and around.

I think the difference in my app is that in addition to the _call BO, I
have 6 others that are filling combo dropdowns. It looks like the
handlers for each of the lists has also gotten added twice to the
NonSerializableEventHandlers which is undoubtedly why that cascade of
field checks goes off recursively for each of the 71 fields in the main
BO.

I hope that you can recommend a fix for this (if my diagnosis is
correct).

Thank you,
Dan

On Thu, 27 Jul 2006 08:50:44 -0500, "Rockford Lhotka"
said:
> The reason the IsDirty is getting reset when I put the
> PropertyHasChanged("") in the overridden OnUnknownPropertyChanged() is
> this:
> protected virtual void PropertyHasChanged(string propertyName)
> {
> ValidationRules.CheckRules(propertyName);
> MarkDirty(true);
> OnPropertyChanged(propertyName);
> }
> But PropertyHasChanged() is only called in a property set block.
> OnUnknownPropertyChanged() triggers the raising of PropertyChanged
> event(s) and does NOT trigger calling any set blocks - only get blocks.
> Yes, data binding is very chatty, in that it reads values a lot. But it
> doesn't set them unless your UI code or the user sets them. If
> PropertyHasChanged() is being called, it is because you have code
> somewhere that is setting one or more properties when a PropertyChanged
> event is handled. Rocky
>
>

DanEssin replied on Wednesday, July 26, 2006

I did some experimentation with raising PropertyChanged("") in my
overridden OnUnknownPropertyChanged() method. It has the nasty
side-effect of resetting the IsDirty flag after a successful save so it
keeps nagging the user that there are unsaved changes.

So far the only thing that seems to work reliably is the following
kludge:
1 - Override OnUnknownPropertyChanged() with an empty method body.
2 - Make IsDirty of BusinessBase browsable
3 - bind it to a 0,0 checkbox using drag-and-drop
4 - every time the user clicks save, flip to the tab that has the
checkbox, set focus to the checkbox, and flip back to their original
position. This seems to reliably get all the changes pushed into the bo
and the object marked dirty.
5 - then exec bindingsource.endedit() and obj.Save()

On Tue, 25 Jul 2006 17:36:34 -0500, "Rockford Lhotka"
said:
> If you are doing this via email you'll need to go to the forum itself to
> get the attachment. It appears as a link in the header of that particular
> post. Rocky
> From: Daniel Essin [mailto:cslanet@lhotka.net]
> Sent: Tuesday, July 25, 2006 5:24 PM
> To: rocky@lhotka.net
> Subject: Re: [CSLA .NET] Redundant Code?
>
> Did I miss something? You mentioned an attachment but I can't find it.
>
> Thanks,
> Dan
>
>
>

RockfordLhotka replied on Wednesday, July 26, 2006

Again, this problem doesn't exist in my testing, or any other apps I'm aware
of. I really don't think the problem with IsDirty getting set is due to the
framework itself. There's something in your code - possibly in your UI -
that is causing this issue. Very possibly you have UI code that is somehow
updating a property on the object due to the PropertyChanged event being
raised - I'm not sure.

What you'll probably need to do is walk through in the debugger from the
point where PropertyChanged("") is raised to see what property is being
changed by your code.

Rocky

> I did some experimentation with raising PropertyChanged("")
> in my overridden OnUnknownPropertyChanged() method. It has
> the nasty side-effect of resetting the IsDirty flag after a
> successful save so it keeps nagging the user that there are
> unsaved changes.

Copyright (c) Marimer LLC