StrataFrame Forum

How to set BO undirty ?

http://forum.strataframe.net/Topic22416.aspx

By Philipp Guntermann - 3/18/2009

Hi,

i have an issue with my maintanance forms allways starting with the maintanance toolstrip showing the save and undo buttons enabled and the navigate buttons disabled.

i guess this is because automations on the form cause the bo to become dirty. ?

so within the bo, i tried this, to set it "undirty":

        protected override void OnIsDirtyChanged(bool DirtyShouldBe)
        {
            if (this.isDirty && this.EditingState ==  BusinessEditingState.Idle)
                this.Save();
            base.OnIsDirtyChanged(DirtyShouldBe);
        }

however, this throws a stackoverflow exception.

So, what is the appropriate way to handle this ?

thanks.

By Trent L. Taylor - 3/18/2009

You created an infinite loop.  The first thing that you need to figure out is why the BO is becoming dirty.  Something is changing a value.  One thing I would do is handle the IsDirtyChanged event, put a break point, then look at the call stack to determine if I could see what is changing.
By Philipp Guntermann - 3/18/2009

hi,

ahem. i tried to figure out where it comes from, but no luck thus far. i put Messagebox.Show(Boname.isDirty.ToString()) infront and at the end of every procedure that i added to the bo and the form.

it happens after the bo is filled, but where, is not clear.

however, i also dont really care about if its dirty at that point or not, because the user hasnt specified to edit or add a row at that time anyways. actually when i press the undo-button on the maintanance-strip after the form appears, everything is how it should be.

cant i just tell the maintanance form to only care about the isdirty-state of the bo if in edit or add mode ?

thanks.

By Philipp Guntermann - 3/18/2009

just put a breakpoint and looked at the stacktrace. whats immediatly happening before the isdirty changed event triggers is that a bo datetime field gets its value for the first datarow in the bo.
By Philipp Guntermann - 3/18/2009

this is what it shows right before the breakpoint:

  MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.raise_IsDirtyChanged(object sender, System.EventArgs e) + 0xa4 Bytes 
  MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.OnIsDirtyChanged(bool DirtyShouldBe) + 0x27 Bytes 
  MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.CurrentView_ListChanged(object sender, System.ComponentModel.ListChangedEventArgs e) + 0x13f Bytes 
  System.Data.dll!System.Data.DataView.OnListChanged(System.ComponentModel.ListChangedEventArgs e = {System.ComponentModel.ListChangedEventArgs}) + 0x10e Bytes 
  System.Data.dll!System.Data.DataView.IndexListChanged(object sender, System.ComponentModel.ListChangedEventArgs e = {System.ComponentModel.ListChangedEventArgs}) + 0x1a Bytes 
  System.Data.dll!System.Data.DataView.IndexListChangedInternal(System.ComponentModel.ListChangedEventArgs e) + 0x4b Bytes 
  System.Data.dll!System.Data.DataViewListener.IndexListChanged(System.ComponentModel.ListChangedEventArgs e) + 0x3c Bytes 
  System.Data.dll!System.Data.Index.OnListChanged.AnonymousMethod(System.Data.DataViewListener listener, System.ComponentModel.ListChangedEventArgs args, bool arg2, bool arg3) + 0x7 Bytes 
  System.Data.dll!System.Data.Listeners<System.Data.DataViewListener>.Notify<System.ComponentModel.ListChangedEventArgs,bool,bool>(System.ComponentModel.ListChangedEventArgs arg1 = {System.ComponentModel.ListChangedEventArgs}, bool arg2 = false, bool arg3 = false, System.Data.Listeners<System.Data.DataViewListener>.Action<System.Data.DataViewListener,System.ComponentModel.ListChangedEventArgs,bool,bool> action = {Method = {Void <OnListChanged>b__2(System.Data.DataViewListener, System.ComponentModel.ListChangedEventArgs, Boolean, Boolean)}}) + 0x75 Bytes 
  System.Data.dll!System.Data.Index.OnListChanged(System.ComponentModel.ListChangedEventArgs e) + 0x9b Bytes 
  System.Data.dll!System.Data.Index.RecordStateChanged(int oldRecord, System.Data.DataViewRowState oldOldState, System.Data.DataViewRowState oldNewState, int newRecord, System.Data.DataViewRowState newOldState, System.Data.DataViewRowState newNewState) + 0xfa Bytes 
  System.Data.dll!System.Data.DataTable.RecordStateChanged(int record1 = 0, System.Data.DataViewRowState oldState1 = Unchanged, System.Data.DataViewRowState newState1 = ModifiedOriginal, int record2 = 2, System.Data.DataViewRowState oldState2 = None, System.Data.DataViewRowState newState2 = ModifiedCurrent) + 0x7f Bytes 
  System.Data.dll!System.Data.DataTable.SetNewRecordWorker(System.Data.DataRow row = {System.Data.DataRow}, int proposedRecord, System.Data.DataRowAction action = Change, bool isInMerge, int position, bool fireEvent = true, out System.Exception deferredException = null) + 0x29d Bytes 
  System.Data.dll!System.Data.DataTable.SetNewRecord(System.Data.DataRow row, int proposedRecord, System.Data.DataRowAction action, bool isInMerge, bool fireEvent) + 0x3d Bytes 
  System.Data.dll!System.Data.DataRow.EndEdit() + 0x48 Bytes 
  System.Data.dll!System.Data.DataRow.this[System.Data.DataColumn].set(System.Data.DataColumn column, object value) + 0xe4 Bytes 
  System.Data.dll!System.Data.DataRow.this[string].set(string columnName, object value) + 0x19 Bytes 

By Trent L. Taylor - 3/18/2009

The stack trace begins (at the bottom) with an edit, so you are going to have to look at the data table to determine the field that is changed.  You may have to look at the row as well:

MyBO.CurrentDataTable.Rows(0).RowState

MyBO.CurrentDataTable.Rows(0)("MyField", Original)
MyBO.CurrentDataTable.Rows(0)("MyField", Current)
By Philipp Guntermann - 3/18/2009

hi,

the line below is:

MyNamespace.Business_Objekte.Basis.MyBO.MyDateTimefield.set(System.DateTime value = {18.03.2009 11:39:59}) Zeile 410 + 0x40

the value is the value of that field in the first datarow from the database.

further below:

MyProject.Business_Objekte.Basis.MyBO.FieldDescriptor.SetValue(object component = { [MyProject.Business_Objekte.Basis.MyBO]}, object value = {18.03.2009 11:39:59}) Zeile 682 + 0x50 Bytes C#
  System.Windows.Forms.dll!System.Windows.Forms.BindToObject.SetValue(object value) + 0x58 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.PullData(bool reformat, bool force) + 0x14f Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.Target_PropertyChanged(object sender, System.EventArgs e) + 0x28 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.DateTimePicker.OnValueChanged(System.EventArgs eventargs) + 0x17 Bytes 
  MicroFour StrataFrame UI.dll!MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker.OnValueChanged(System.EventArgs eventargs) + 0x36 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.DateTimePicker.Value.set(System.DateTime value) + 0x14d Bytes 
  [Übergang von Systemeigen zu Verwaltet] 
  [Übergang von Verwaltet zu Systemeigen] 
  System.dll!System.ComponentModel.ReflectPropertyDescriptor.SetValue(object component = {MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker, Value: 18.03.2009 11:39:59}, object value = {18.03.2009 11:39:59}) + 0xe3 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.SetPropValue(object value) + 0xc9 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.PushData(bool force) + 0x71 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.UpdateIsBinding() + 0x60 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.CheckBinding() + 0x235 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Binding.SetListManager(System.Windows.Forms.BindingManagerBase bindingManagerBase) + 0xe7 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.ListManagerBindingsCollection.AddCore(System.Windows.Forms.Binding dataBinding = {System.Windows.Forms.Binding}) + 0x2f Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.BindingsCollection.Add(System.Windows.Forms.Binding binding) + 0x32 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.BindingContext.UpdateBinding(System.Windows.Forms.BindingContext newBindingContext, System.Windows.Forms.Binding binding) + 0x8d Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.UpdateBindings() + 0x49 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xef Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnParentBindingContextChanged(System.EventArgs e) + 0x39 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xd2 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnParentBindingContextChanged(System.EventArgs e) + 0x39 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xd2 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnParentBindingContextChanged(System.EventArgs e) + 0x39 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xd2 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnParentBindingContextChanged(System.EventArgs e) + 0x39 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xd2 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContextInternal.set(System.Windows.Forms.BindingContext value) + 0x8a Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.BindingContext.set(System.Windows.Forms.BindingContext value) + 0x5 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.BindingContext.get() + 0x4e Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContextInternal.get() + 0x75 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.SplitContainer.BindingContext.get() + 0x5 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContextInternal.get() + 0x75 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContext.get() + 0x5 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContextInternal.get() + 0x75 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.BindingContext.get() + 0xc Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContextInternal.get() + 0x75 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.BindingContext.get() + 0x5 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.UpdateBindings() + 0x28 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xef Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnParentBindingContextChanged(System.EventArgs e) + 0x39 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.Control.OnBindingContextChanged(System.EventArgs e = {System.EventArgs}) + 0xd2 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.OnCreateControl() + 0x48 Bytes 
  System.Windows.Forms.dll!System.Windows.Forms.UserControl.OnCreateControl() + 0xa Bytes 
  MicroFour StrataFrame UI.dll!MicroFour.StrataFrame.UI.Windows.Forms.ThemedContainer.OnCreateControl() + 0xa Bytes 

By Philipp Guntermann - 3/18/2009

ive put code in the isdirty event to show a messagabox with all original and current fieldvalues of the modified-state row.

for every field, the original and current values are the same.

By Philipp Guntermann - 3/18/2009

the problem has something todo with binding to the datetime-picker control.

on the form there are two of thoose. if i unbind them by selecting Business-Object = none in the property editor, the form behaves correctly (bo doesnt get dirty). however off course then they are not bound Smile

i am setting default values to thoose from the bo's SetDefaultValues procedure. however this aint the cause of the problem, because if i comment theese lines out, the bo still gets dirty.

the datetime picker controls are set up with following property values:

BindableValue = 01.01.1800
BindingField = MyDateTimeField
BindingProperty = Value
BindingUpdateMode = OnPropertyChanged
BusinessObject = MyBO
ClearOnNULL = True
CustomFormat = dd.MM.yyyy HH:mm:ss
Format = Custom
MaxDate = 31.12.9998
MinDate = 01.01.1753
NullDateValue = 01.01.1800
ShowUpDown = True
StripTimeFromValue = False
Value = 01.01.1800

By Philipp Guntermann - 3/19/2009

any ideas ?..
By Philipp Guntermann - 3/20/2009

hi,

the issue is solved by setting the ClearOnNULL-Property of the DateTime-Picker to false.