By StarkMike - 4/17/2007
Any idea as to why I would get this error? I searched the forum and only found one other post and I'm not sure that the previous thread applies to me.
|
By Trent L. Taylor - 4/17/2007
This can come from a number of different places...where are you getting it? It is most likley a BO data source or localization key that is being requested and does not exist in the environment.
|
By StarkMike - 4/17/2007
It happens when I use a BO as a search field in a browse dialog. Below are a couple of screenshots to help illustrate.P.S. The second image illustrates a problem with browse dialogs that I mentioned about the DevExpress wrapped one...it appears it is doing the same thing with the StrataFrame one. Not sure if the problem is related.
|
By Trent L. Taylor - 4/17/2007
You are having a serialization issue with your form. This means that when you make changes the designer does not add all of the designer code. This can happen under a lot of different circumstances. If you simply take and create a new SF maintenance form, drop on the browse dialog, and add the search fields, etc. The form designer will serialize the collections and settings properly. Without actually getting my hands on your form and project I cannot tell you why your browse dialog settings are not being properly serialized.The first test would be to create a new form with a new browsedialog to see if all of the settings "stick" then start to work backwards to see what is the catalist in your environment.
|
By StarkMike - 4/17/2007
OK. thanks, i'll digg in. Digg in.... get it?
|
By Trent L. Taylor - 4/17/2007
hehe...got it. I know that there is something within your environment that is causing the problem because this is something that is done in high volume...so I would like to figure out what is going on within your project so we can help prevent it in the future!
|
By StarkMike - 4/17/2007
Ok, so I tried it two different ways and got the same results... a blank List Population Settings screen.First I created a SF Maintenance form and the only thing I dropped on it was a SF Browse dialog. I set the Search Field to LocationID and then setup the BO using the LocationsBO. I clicked Ok until I was back to the form.... saved it and went back in and the List Population Settings came up blank. Secondly, I did the same thing with just a standard SF Form... didnt know if there might have been something different between a maintenance form and a standard form. Hmmm....
|
By StarkMike - 4/19/2007
Hello?
|
By Trent L. Taylor - 4/19/2007
If you create a maintenance form or a standard form you will see that they both inherit MicroFour.StrataFrame.UI.WIndows.Forms.StandardForm. A MaintenanceForm is just a template with a header and maintence form toolstrip already dropped on the form.I cannot reproduce your behavior as much as I am really trying to. If you create a new project, create a BO, drop on a browse dialog, and try to go through the same steps do you get the same results? Also, are you dropping the browse dialog directly on the form or is this an inherited browse dialog? Is the browse dialog dropped on a user control? Last, could you create a simple project that reproduces the behavior so I can test it on this side? Thanks.
|
By StarkMike - 4/20/2007
Ok, Here's what I tried. I'm using ver 6.3.3 of DevExpress and ver 1.6 of StrataFrame. I created a blank StrataFrame application...created a BO based on the customers table in the StrataFrame Sample database. I dropped the CustomerBO on the form and dropped the BrowseDialog on the same StrataFrame StandardForm. Then I setup the BrowseDialog and it produced the same results.
I opened this project on two other computers including my own. One of them even had Visual Studio SP 1 installed and we got the same results. On my test computer I uninstalled SF1.6 and re-installed SF1.5 only to discover that this functionality didnt exist in 1.5
I've attached the project I created.
I am including screenshots that show my version of Visual Studio.
My Visual Studio Version
Visual Studio Version of my collegue
|
By Trent L. Taylor - 4/20/2007
I have made a change to the extensibility DLL that should resolve your problem. The instructions on implementing the changes are below. As a side note, one thing I noticed that wasn't right within your application was your use of the SetConnections() method. This is really something that should never be called outside of the SetDataSources method in the AppMain.vb file. You connections should already be established before you starting showing and loading forms....at least in most cases. - Close down Visual Studio
- Drag the DLL into the c:\windows\assembly folder (GAC)
- Copy the DLL and XML file to c:\program files\common files\microfour\strataframe
- Re-open Visual Studio and you should be good to go!
|
By StarkMike - 4/20/2007
Ok I replaced the old extensibility file with the one you provided PLUS i replaced the extensibility file in C:\Program Files\MicroFour\StrataFrame\Assemblies with the one you just gave me.
However now when I open the SearchFields dialog and click on a field and then click edit... the dialog just closes... no error message...just disappears...
I removed the field and then clicked Add... it let me setup the new field but then i clicked ok it didnt add the field to the list...
|
By Trent L. Taylor - 4/20/2007
I don't think you got it replaced then. I am pretty confident that the issue has been resolved and the behavior you are getting is indicitive of a version conflict. I went through this a number of times before I posted the fix. Are you sure that you updated the GAC? Try manually deleted the Extensibility DLL in the GAC and the adding it back with the new one.
|
By StarkMike - 4/20/2007
I tried that two or three times and its still not working... is there something i need to do to manually register the file once i've put it in the GAC? I remember vb6 you used to have to run regsvr32...What is also interesting is that I didnt have an Extensibility xml file in Common Files\StrataFrame until i added the one you gave me. I replaced the extensibility dll you just gave me with the original one and the Search Fields Criteria dialog came right up... what am i doing wrong?
|
By StrataFrame Team - 4/23/2007
Mike, it could be that the extensibility DLL that we gave you is getting a MissingMethodException or something like that. If some method signature within one of the core DLLs changed, it could be that an exception is being thrown and snuffed by VS (it likes to do that so that 3rd party addins by guys like us don't kill VS ) Let me zip up the rest of the core DLLs and replace all of them and tell me if you can open the browse dialog.
|
By StrataFrame Team - 4/23/2007
Here are the DLLs for you.
|
By StarkMike - 4/23/2007
Ok. Great! That fixed those problems. Everything works in design time again. i deleted the browsedialog and re-created it and STILL got that "given key" problem... what should I be looking for? My other browse dialogs in my program work... not sure whats going on...
|
By Trent L. Taylor - 4/23/2007
The given key problem was the way you had your connection strings setup, at least in the sample you gave me. That is why I mentioned that your use of the SetConnections() method was not correct. Just to see if this is your problem, hard code the connection string and do not call the SetConnections method....from the AppMain or anywhere else.Databasics.DataSources(New SqlDataSourceItem("","server=localhost;integrated security=SSPI;database=MyDatabase;")
|
By StarkMike - 4/23/2007
I tried removing setconnections from AppMain and it still did it. I looked back and realized that I didnt explain where I was getting this error i just said I was getting it... Allow me to explain where I get it...When I run my app and bring up a browse dialog... i have a combo box in the search fields criteria that represents locations... when i choose a location from the combo box and then click search is when I get the error... If i just click search and not choose a location it works fine. I'll include my stack dump just to help out. The given key was not present in the dictionary. Exception (KeyNotFoundException): Source="mscorlib"; Target=null; Tag=null; Message = "The given key was not present in the dictionary." Environment: ThreadIdentity="" DateTime=["2007-04-23 12:44:25.723"] ThreadName=null WindowsIdentity="STRUSS\MMurphy" ThreadId="11" DemoVersion="True" DomainName="STI.vshost.exe" OSVersion=["Microsoft Windows NT 5.1.2600 Service Pack 2"] MachineName="1LPMMURPHY2" UserName="MMurphy" Remaining Stack Trace -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= at System.ThrowHelper.ThrowKeyNotFoundException() at System.Collections.Generic.Dictionary`2.getItem(TKey key) at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.BuildWhereElement(SearchFieldItem SearchField) at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.BuildWhereElement(Int32 ParameterIndex) at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.BuildSearchWhereClause() at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.Search() at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.ExecuteSearch() at MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogwindow.tsiSearchClick(Object sender, EventArgs e) at System.Windows.Forms.ToolStripItem.RaiseEvent(Object key, EventArgs e) at System.Windows.Forms.ToolStripButton.OnClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleClick(EventArgs e) at System.Windows.Forms.ToolStripItem.HandleMouseUp(MouseEventArgs e) at System.Windows.Forms.ToolStripItem.FireEventInteractive(EventArgs e, ToolStripItemEventType met) at System.Windows.Forms.ToolStripItem.FireEvent(EventArgs e, ToolStripItemEventType met) at System.Windows.Forms.ToolStrip.OnMouseUp(MouseEventArgs mea) at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks) at System.Windows.Forms.Control.WndProc(Message& m) at System.Windows.Forms.ScrollableControl.WndProc(Message& m) at System.Windows.Forms.ToolStrip.WndProc(Message& m) at System.Windows.Forms.Control.ControlNativewindow.OnMessage(Message& m) at System.Windows.Forms.Control.ControlNativewindow.WndProc(Message& m) at System.Windows.Forms.Nativewindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) Hope this helps.
|
By StrataFrame Team - 4/24/2007
It could be the business object to which that browse dialog is bound. Either you have a field with differing case between the different collections describing the field, or you have a custom property on the business object and you're trying to include it in the search fields. Looking at the code, the only dictionary referenced is the FieldDbTypes dictionary on the dictionary. Check the BO at runtime and make sure that it contains a definition for every field that is contained within the search fields for the browse dialog.
|
By StarkMike - 4/24/2007
Yup... Thats the problem... it didnt notice it until now. I created another BO based on the same table with just a fill method and thats when I discovered it. Can I not base a search field on a custom property in a BO?
|
By StarkMike - 4/24/2007
Here is the custom property that I was basing a search field on: ''' <summary> ''' LocationID ''' </summary> ''' <remarks></remarks> <Browsable(False), _ BusinessFieldDisplayInEditor(), _ Description("LocationID"), _ DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)> _ Public ReadOnly Property [LocationID]() As System.Int32 Get Try Using loBo As New DivisionsBO loBo.FillByDivisionID(Me.DivisionID) Return loBo.LocationID End Using Catch ex As Exception MessageForm.ShowMessageByKey("Ems.DefaultErrorMessage", ex.Message) Ems.HandleException(Me, ex) Throw End Try End Get End Property
|
By Greg McGuffey - 4/24/2007
I have no idea about your question on if a Custom column can be used in a search, but one comment about how you're getting the LocationID. I'd use a scalar method to return the custom field. I.e. I wouldn't fill the BO, the return the property, I'd have a method just for this that used ExecuteScalar() to get the field. I.e. in DivisionsBO I'd have a method something like GetLocationByDivision(divisionID as Integer). Inside that method I'd do something like (code not tested, just typed here from memory...don't be surprised if it's not quite 100% ):
Public Function GetLocationByDivision(divisionID as Integer) As Integer
Dim id As Integer
Using cmd As New SqlCommand
' Using the appropriate column and table names of course...
cmd.CommandText = "Select LocationID From DivisionTable Where DivisionID = @divisionID"
cmd.Parameters.Add("@divisionID",int)
cmd.Parameters("@divisionID").Value = divisionID
Dim ret As Object = cmd.ExecuteScalar(cmd)
If ret Is DBNull.Value Then
id = 0
Else
id = CType(ret,Integer)
End If
End Using
Return id
End Function
This has a few advantages:
- ExecuteScalar() is a lot faster.
- The method handles dealing with a NULL being returned from the DB. A zero is returned in this case. It makes error checking a bit easier.
- You can use this other places if needed.
Just something I picked up somewhere in the forum from Trent or Ben and thought I'd pass it one.
|
By StarkMike - 4/24/2007
Thanks Greg! I ALWAYS appreciate advice.
|
By StrataFrame Team - 4/25/2007
Mike, No, you cannot search off of a custom property. The problem is that the browse dialog dynamically creates an SQL statement to retrieve records. When a search field is added to the browse dialog, the browse dialog thinks that the field is a valid field in the DB and it can be included in the WHERE of the created SQL statement. Since a custom property does not have a valid backing column in the database, it can't be included in the query.
|
By StarkMike - 4/26/2007
Hey Greg,I have a question about your post: I have no idea about your question on if a Custom column can be used in a search, but one comment about how you're getting the LocationID. I'd use a scalar method to return the custom field. I.e. I wouldn't fill the BO, the return the property, I'd have a method just for this that used ExecuteScalar() to get the field. I.e. in DivisionsBO I'd have a method something like GetLocationByDivision(divisionID as Integer). Inside that method I'd do something like (code not tested, just typed here from memory...don't be surprised if it's not quite 100% ):
Public Function GetLocationByDivision(divisionID as Integer) As Integer Dim id As Integer Using cmd As New SqlCommand ' Using the appropriate column and table names of course... cmd.CommandText = "Select LocationID From DivisionTable Where DivisionID = @divisionID" cmd.Parameters.Add("@divisionID",int) cmd.Parameters("@divisionID").Value = divisionID Dim ret As Object = cmd.ExecuteScalar(cmd) If ret Is DBNull.Value Then id = 0 Else id = CType(ret,Integer) End If End Using Return id End Function
This has a few advantages: - ExecuteScalar() is a lot faster. - The method handles dealing with a NULL being returned from the DB. A zero is returned in this case. It makes error checking a bit easier. - You can use this other places if needed.
Just something I picked up somewhere in the forum from Trent or Ben and thought I'd pass it one. After I create this method in my BO...I'll still have to instantiate the BO in order to call the function, right? Isn't instantiation where I'll take a performance hit so it wouldnt matter if I filled the BO or just called this scalar function?
|
By StrataFrame Team - 4/26/2007
If you've got enough information within the business object to calculate the value without needing to execute a database query, then you're always better off calculating it locally than querying the database. However, if the custom property cannot be calculated or built from the fields that are already within the business object, then it's OK to go ahead and run a database query to retrieve the value. You won't have to worry about taking the performance hit of instantiation, because the method is an instance method so you'll already have the bo instantiated.On a side note, be careful of the ExecuteScalar method. It does not always return a value. For instance, if you try to execute this: "Select LocationID From DivisionTable Where 1=0" it will not return DBNull.Value; instead, it will return Nothing (or null in C#). Now, if you cast Nothing as an integer, you'll get a 0 (since 0 is the default value for the integer value type), but if you're using ExecuteScalar() to retrieve a string, be careful of the difference between a DBNull.Value returned and a Nothing returned.
|
By Greg McGuffey - 4/26/2007
Based on what Ben said, if it turns out that you need to get data from a query, then the code as I wrote it would need a BO instantiated. My understanding was that using ExecuteScalar() is MUCH faster than loading a whole datatable and the BO, even if it is only one row. So, the code to use this would something like...
Using loBo As New DivisionsBO
Return loBo.GetLocationByDivision(Me.DivisionID)
End Using
I didn't know (and still don't exactly understand) that Nothing (null in C#) could be returned. So there would have to be code to handle that also.
Finally, you could potentially speed this up even more by directly querying for Location ID in your custom property. Then you would not need to instantiate the DivisionsBO at all. However, then you have SQL spread around, so I'd likely not use that strategy.
Finally, I suppose that you could share the method, to skip the need for an instantiation, but I don't know if this is a good idea.
|