StrataFrame Forum

DateTimePicker dirtying BO

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

By Greg McGuffey - 2/11/2008

I have a date field that allows NULLs in the db (the date can legitimately not be set). I have the BO to return/set 1/1/1800 for NULL dates (I have Date.Parse("1800/1/1") as my replacement value). I then have a SF DateTimePicker control bound to this. When I navigate to a record with a NULL date, it makes the BO dirty. I must be doing something wrong, but can't figure out what. Any ideas?
By Trent L. Taylor - 2/11/2008

Hmmm....by default this shouldn't be happening since the Get is where the logic will reside for the NULL value.  So something is forcing the Set to be called.  You might put a breakpoint in the Set of the property and then look at the call stack to see where the Set is coming from.  It might at least get you going in the right direction.
By Greg McGuffey - 2/11/2008

Well, I did that and it appears that the datetimepicker is causing the problem. Here is the complete call stack from the Set method:

BusinessObjects.dll!FOXSystems.RAMS.BusinessObjects.Project.ProjectActionItemsBO.set_ResolutionDate(Date value = #1/1/1800#) Line 415Basic

BusinessObjects.dll!FOXSystems.RAMS.BusinessObjects.Project.ProjectActionItemsBO.Field_ResolutionDate_Descriptor.SetValue(Object component = {FOXSystems.RAMS.BusinessObjects.Project.ProjectActionItemsBO}, Object Value = #1/1/1800#) Line 869 + 0x45 bytesBasic


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

MicroFour StrataFrame UI.dll!MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker.OnBindableValueChanged() + 0x1a bytes

MicroFour StrataFrame UI.dll!MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker.BindableValue.set(System.DateTime value) + 0x2c5 bytes

[Native to Managed Transition]

[Managed to Native Transition]



--> I'm guessing that the the two different values here are the old value (2/8/2008) and the new value (1/1/1800...NULL).

System.dll!System.ComponentModel.ReflectPropertyDescriptor.SetValue(object component = {MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker, Value: 2/8/2008 12:00:00 AM}, object value = {1/1/1800 12:00:00 AM}) + 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.ReadValue() + 0xa bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.RefreshValue(System.Windows.Forms.Control ControlToRefresh = {MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker, Value: 2/8/2008 12:00:00 AM}, string PropertyName = "BindableValue") + 0x3b bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.RefreshControl(MicroFour.StrataFrame.UI.Windows.Forms.IBusinessBindable ControlToRefresh = {MicroFour.StrataFrame.UI.Windows.Forms.DateTimePicker, Value: 2/8/2008 12:00:00 AM}, bool DataPresent) + 0x269 bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.RefreshBoundControls() + 0x89 bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.raise_Navigated(MicroFour.StrataFrame.Business.NavigatedEventArgs e = {MicroFour.StrataFrame.Business.NavigatedEventArgs}) + 0xbb bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.OnNavigated(MicroFour.StrataFrame.Business.NavigatedEventArgs e) + 0x8 bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.Navigate(MicroFour.StrataFrame.Business.BusinessNavigationDirection Direction, int AbsoluteIndex, object[] PrimaryKeyValues, bool AttemptToCheckRules, bool IsRefill) + 0x3c8 bytes

MicroFour StrataFrame Business.dll!MicroFour.StrataFrame.Business.BusinessLayer.NavigateToPrimaryKey(object[] PrimaryKeyValues) + 0x13 bytes

RamsUI.dll!FOXSystems.RAMS.UI.Forms.Controls.SynchListView.SetBOValue(Integer id = 2) Line 108 + 0x4d bytesBasic

RamsUI.dll!FOXSystems.RAMS.UI.Forms.Controls.SynchListView.NavByList() Line 131 + 0x18 bytesBasic

RamsUI.dll!FOXSystems.RAMS.UI.Forms.Controls.SynchListView.SynchListView_SelectedIndexChanged(Object sender = {FOXSystems.RAMS.UI.Forms.Controls.SynchListView}, System.EventArgs e = {System.EventArgs}) Line 199 + 0x9 bytesBasic




---> User action (selecting an item in a listview) causes the SelectedIndexChangedEvent above





System.Windows.Forms.dll!System.Windows.Forms.ListView.OnSelectedIndexChanged(System.EventArgs e) + 0x6a bytes

System.Windows.Forms.dll!System.Windows.Forms.ListView.WmReflectNotify(ref System.Windows.Forms.Message m) + 0x80e bytes

System.Windows.Forms.dll!System.Windows.Forms.ListView.WndProc(ref System.Windows.Forms.Message m) + 0x9d bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativewindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativewindow.WndProc(ref System.Windows.Forms.Message m) + 0x36 bytes

System.Windows.Forms.dll!System.Windows.Forms.Nativewindow.DebuggableCallback(System.IntPtr hWnd, int msg = 8270, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes

[Native to Managed Transition]

[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.Control.SendMessage(int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x42 bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ReflectMessageInternal(System.IntPtr hWnd, ref System.Windows.Forms.Message m = {msg=0x4e (WM_NOTIFY) hwnd=0x1009b6 wparam=0xf0a14 lparam=0x4e5e1c8 result=0x0}) + 0x3e bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.WmNotify(ref System.Windows.Forms.Message m = {msg=0x4e (WM_NOTIFY) hwnd=0x1009b6 wparam=0xf0a14 lparam=0x4e5e1c8 result=0x0}) + 0x2f bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x688 bytes

System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x45 bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativewindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativewindow.WndProc(ref System.Windows.Forms.Message m) + 0x36 bytes

System.Windows.Forms.dll!System.Windows.Forms.Nativewindow.DebuggableCallback(System.IntPtr hWnd, int msg = 78, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes

[Native to Managed Transition]

System.Windows.Forms.dll!System.Windows.Forms.Nativewindow.DefWndProc(ref System.Windows.Forms.Message m = {msg=0x201 (WM_LBUTTONDOWN) hwnd=0xf0a14 wparam=0x1 lparam=0x2c009d result=0x0}) + 0x94 bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.DefWndProc(ref System.Windows.Forms.Message m) + 0xc bytes

System.Windows.Forms.dll!System.Windows.Forms.ListView.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0xf3 bytes

System.Windows.Forms.dll!System.Windows.Forms.ListView.WndProc(ref System.Windows.Forms.Message m) + 0xef bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativewindow.OnMessage(ref System.Windows.Forms.Message m) + 0xd bytes

System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativewindow.WndProc(ref System.Windows.Forms.Message m) + 0x36 bytes

System.Windows.Forms.dll!System.Windows.Forms.Nativewindow.DebuggableCallback(System.IntPtr hWnd, int msg = 513, System.IntPtr wparam, System.IntPtr lparam) + 0x57 bytes

[Native to Managed Transition]

[Managed to Native Transition]

System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(int dwComponentID, int reason = -1, int pvLoopData = 0) + 0x2f1 bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason = -1, System.Windows.Forms.ApplicationContext context = {System.Windows.Forms.ApplicationContext}) + 0x17d bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x53 bytes

System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x2e bytes

MicroFour StrataFrame UI.dll!MicroFour.StrataFrame.Application.StrataFrameApplication.RunApplication() + 0x296 bytes

RAMS.NET.exe!FOXSystems.RAMS.AppMain.Main() Line 35 + 0x6 bytesBasic

[Native to Managed Transition]

[Managed to Native Transition]

mscorlib.dll!System.AppDomain.nExecuteAssembly(System.Reflection.Assembly assembly, string[] args) + 0x17 bytes

mscorlib.dll!System.Runtime.Hosting.ManifestRunner.Run(bool checkAptModel) + 0xd2 bytes

mscorlib.dll!System.Runtime.Hosting.ManifestRunner.ExecuteAsAssembly() + 0x81 bytes

mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext, string[] activationCustomData) + 0x64 bytes

mscorlib.dll!System.Runtime.Hosting.ApplicationActivator.CreateInstance(System.ActivationContext activationContext) + 0x7 bytes

Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssemblyDebugInZone() + 0x55 bytes

mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x3b bytes

mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x81 bytes

mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x40 bytes




I'll also include the SetBOValue (perhaps not the best name Ermm ), which simply navigates to the PK of the record selected in the list:

Public Sub SetBOValue(ByVal id As Integer)

'-- Only do anything if the provided ID isn't already

' the current value.

If id > 0 AndAlso (Me.DataBO.CurrentRowIndex < 0 OrElse CInt(Me.DataBO.Item(Me.DataBO.PrimaryKeyField)) <> id) Then

Me.DataBO.NavigateToPrimaryKey(id)

End If

End Sub




I'm not seeing anything in my code that is causing this. I'm wondering if I have the DateTimePicker setup correctly.
By Greg McGuffey - 2/11/2008

It is definitely something related to the DateTimePicker and the field in the BO using an alternate value for NULLs. If I unbind the datetimepicker, all is well. I have another date field on the form that can't be NULL and all is well there. If I switch between two rows that are NULL for this field (ResolutionDate), no problems. If I switch between two fields that have dates, then no problems.



I have the BO set to return an alternate value if the DB field is NULL/ set NULL if the BO field is the alternate value. The alternate value I'm using is 1/1/1800. I set this alternate value as Date.Parse("1800/1/1") and also tried #1/1/1800# in BO mapper. There appeared to be no difference between the two. The DateTimePicker is set to use 1/1/1800 as its NULL value and it is set to strip time from the date. I must be missing something....Crazy
By Trent L. Taylor - 2/12/2008

Greg,

I believe you, but there is some else in the formula that is causing this to manifest itself, which is probably the NULL settings.  Send me a sample with a BO set just like the one that is causing the issue so I can debug what is going on.  I am having a harder time on this side reproducing the exact same scenario. Ermm

By Greg McGuffey - 2/12/2008

Trent,



Here is a sample. You will need to add a column to the Orders table so there is a NULL date column. There is a sql script in the project directory you can run.



Tests:

- The first time you open it, all the rows will have null for the new date column and all will work fine.

- Move the first row, hit edit and enter a date for the received date, save.

- Now move to the next row. You will notice two things: the record is now dirty and you can't navigate any longer (no idea why).

- If you unbind the received date datetimepicker, it works again.


By Greg McGuffey - 2/13/2008

Bump... BigGrin
By Greg McGuffey - 2/15/2008

Any progress on this? I need to make a decision quickly about whether to just bail with using the DateTimePicker. As it stands now, it won't work (well) with any field that is using NULLs.
By Trent L. Taylor - 2/15/2008

Greg,

I have this on my list to look at....I have some major time contraints on me this week...which is no different from any other week Smile ...but I have not been able to look at this yet.  When I sit down to go through teh remaining items on the "to-do" list for 1.6.5 I was planning on looking at this then.  Sorry for the wait, but I have a ton on my plate this week (including my evenings) so I just haven't gotten around to it...but it is on my list.

By Greg McGuffey - 2/15/2008

Totally understand. Let me me know! Thanks! BigGrin