Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
I have been using the Browse Dailog on a few screens and its working out very well. Typically I use it with a text Box , say to do a look up on a cutomer file. The user would enter text into the text box, and I first do an exact lookup on the Customer table to see if the cutomer number exists. If it does, I don't call the Browse Dialog. If it does not, i assume the user has entered 'part' of the name and I call a browse dialog with a few colums ftom the customer file set up. All this is working perfectly. Now I find I need this funtionality on say 20 forms. What I had started to do was repeat the same text box and browse dialog on each form, but thought there must be a better way . Some guidance of setting up a Customer Lookup class (based on a text Box that calls the browse dialog) that I can then drop on each of my forms.I can manage searching the tables etc but not sure how to set up the BrowseDialog in code as opposed to from within a form. Pseudo code of the sort of thing I'm lookin at would be: public class Textbox : MicroFour.StrataFrame.UI.Windows.Forms.Textbox { private System.Drawing.Color originalBackgroudColour; protected override void OnEnter(EventArgs e) { //-- Run Base Class Code base.OnEnter(e); protected override void OnLeave(EventArgs e) { //-- Run the Base Code for the textbox base.OnLeave(e); // Pseudo Code SearcCustomer(this.tetBox) If NotFound {Call BrowseDialog} } } // End textBox
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
There has got to be some issue with references/bo names. In cases like this, I'd suggest creating a sample app focused on this problem. Start with a solution with a single project. Put a BO in it and see if you can get it work. Then try adding a second project and a BO in it, see if it works. The main form would just have some code in the load event handler that you've been working on: set boString, boType and try to create an instance using CreateInstance. Post the solution that doesn't work with a stack trace. Oh, and make BOs that point the StrataFrameSample database (like to the Customers table) so I can test it out quickly.
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Ok Greg.... will give that a try .
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Hi Greg. I took your advice and have set up two projects to come as close as possible to the live project I was working on. The first project is just a BO Library with the Customer and Product tables from the SF sample database (in TEST_BOLibrary folder). The second is a very basic SF maintnance screen project (TEST_APP) , and on it I have a button with just a few lines of code ....still getting the problem with GetType. On the maintanance Form, I have referenced the BO Library and the cusotmer table is displaying fine on the Maintanance screen but the reflection bit still not working I would appreciate it if you could take a look..
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
I'll take a look at this either later today or tomorrow.
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Hi. just wondering if this has dropped off the radar ??
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Ah...oops. I'll take a look at it today. Sorry for the delay.
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
You were really, really close.  You had done two things not quite right. 1. When you looked up the type, you used Type.GetType(). If you use this you have to supply a fully qualified name, including assembly info. A pain. Instead use the SF helper function GetTypeFromReferencedAssemblies(). 2. You didn't cast the object returned by Actvator.CreateInstance to be a BusinessLayer. Here is the complete code for the form. namespace Test_APP
{
public partial class CustForm : MicroFour.StrataFrame.UI.Windows.Forms.StandardForm
{
public CustForm()
{
InitializeComponent();
}
private void button1_Click( object sender, EventArgs e )
{
string boString = "TEST_BOLibrary.SFCustBO";
MicroFour.StrataFrame.Business.BusinessLayer bo = null;
//-- Use GetTypeFromReferencedAssemblies because BO is in different assembly than form.
//-- Wrong --> Type oType = Type.GetType( boString); can't find type in current assembly.
Type oType = MicroFour.StrataFrame.Tools.Common.GetTypeFromReferencedAssemblies( boString );
//-- Need to cast object returned by Activator.CreateInstance to a BusinessLayer
//-- Wrong --> bo = Activator.CreateInstance(oType); Type mismatch as CreateInstance returns an object.
bo = (MicroFour.StrataFrame.Business.BusinessLayer)Activator.CreateInstance( oType );
//-- Just access the BO to ensure that it got created.
MessageBox.Show( string.Format( "Number of records in bo: {0}", bo.Count ) );
}
private void sfCustBO1_ParentFormLoading_1()
{
//-- I changed this to load just the top 100 records...faster for testing.
this.sfCustBO1.FillTopN( 100 );
}
}
} In the code above you'll see a reference to the FillTopN method on SFCustBO. I added this instead of the fill all just to speed up loading (yeah, I can be impatient  ) //-- In SFCustBO
public void FillTopN( int numberToFill )
{
this.FillDataTable( string.Format( "Select Top {0} * From {1}", numberToFill, this.TableName ) );
}
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Thanks for that Greg. I feel I am making progress now. I am at the stage where I have (using Reflection) created the Buiness Object and the Browse Dialog, but am unsure of the next steps. I am getting an error at Step 10 below(Object reference not set to an instance of an object) which is probably because I have left out a few steps. I am not sure how to progress from Step4 below to Step 10. At this stage, say I have just one or two columns to include in the browse. When manually inputting the properties on the Browse Dialog, there just seems to be a)BrowseResultsLayout b)FormLayout c)SearchFields which need to be populated. Is this the same if I am programatically creating the controls? Some pointers as to what I am missing below would be very helpful. // ---- Assign Strings (There will be taken in as Parameters when its all working string boString; string selectString; boString = "Kernel_BOLibrary.SmaBO"; selectString = "Select * from SMA"; // --- 1. Setup the Business Object MicroFour.StrataFrame.Business.BusinessLayer bo = null; Type oType = MicroFour.StrataFrame.Tools.Common.GetTypeFromReferencedAssemblies(boString); bo = (MicroFour.StrataFrame.Business.BusinessLayer)Activator.CreateInstance(oType); string boName; boName = bo.CurrentDataTable.ToString(); bo.FillDataTable(selectString); MessageBox.Show("No of records in BO" + " " + boName + " " + bo.Count);
// --- 2. Set up a Generic Browse Dialog string bdString; bdString = "MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog"; MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog bd = null; Type oBDType = MicroFour.StrataFrame.Tools.Common.GetTypeFromReferencedAssemblies(bdString); bd = (MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog)Activator.CreateInstance(oBDType);
// --- 3. Start assigning properties for the generic BrowseDialog bd.BusinessObjectToPopulate = bo; bd.BusinessObjectType = oType.ToString();
// --- 4. Create the columns.... in live class, I will need to paramterise this....can I just loop around or do I need reflection here again ?? MicroFour.StrataFrame.UI.Windows.Forms.BrowseColumnItem bdCol01 = new MicroFour.StrataFrame.UI.Windows.Forms.BrowseColumnItem(); bdCol01.ColumnHeaderText = "Col1 header"; bd.BrowseResultsLayout.BrowseColumns.Add(bdCol01);
// --- 5. Create the setting ....do I need this MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogLayoutSettings bdSett1 = new MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialogLayoutSettings();
// --- 10. Call up the Browse Dialog bd.ShowDialog(true);
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Just wondering...any thoughts on this ??
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
If you decide to go this route, and configure the BrowseDialog in code (rather than creating a subclass that is already configured) you don't need to use reflection...you know it is going to be a BrowseDialog... // --- 2. Set up a Generic Browse Dialog
MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog bd = new MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog(); To configure the BrowseDialog, the easiest is to just look at the designer file of subclassed BrowseDialogs. You can see what code you need and what sort of data you'll need to parametrize. E.g. take a look at the Customers and orders BDs in the sample.
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
I have changed the code now, and am getting the browse dialog screen up ok. However, when I enter any data in the Search Box, and click Search, I get an error up: ---> The Given Key was not present in the dictionary <--- Error screen is attached. I have more or less copied the customerBO in the samples you sent on the Generic Browse. My Code is: // ---- Assign Strings (There will be taken in as Parameters when its all working string boString string selectString; boString = "Kernel_BOLibrary.SmaBO"; selectString = "Select * from SMA";
// --- 1. Setup the Business Object using reflection as it can be ANY business Object and we dont know whcih one MicroFour.StrataFrame.Business.BusinessLayer bo = null; Type oType = MicroFour.StrataFrame.Tools.Common.GetTypeFromReferencedAssemblies(boString); bo = (MicroFour.StrataFrame.Business.BusinessLayer)Activator.CreateInstance(oType); string boName; boName = bo.CurrentDataTable.ToString(); bo.FillDataTable(selectString); MessageBox.Show("No of records in BO" + " " + boName + " " + bo.Count);
// --- 2. Set up a Generic Browse Dialog MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog bd = new MicroFour.StrataFrame.UI.Windows.Forms.BrowseDialog(); // --- 3. Start assigning properties for the generic BrowseDialog bd.BusinessObjectToPopulate = bo; bd.BusinessObjectType = "SmaBO"; bd.ViewResultsAsLedgerCard = true;
// --- 4a. Create the columns.... in live class, I will need to paramterise this....can I just loop around or do I need reflection here again ?? MicroFour.StrataFrame.UI.Windows.Forms.BrowseColumnItem bdCol01 = new MicroFour.StrataFrame.UI.Windows.Forms.BrowseColumnItem(); bdCol01.ColumnHeaderText = "Name"; bdCol01.ColumnHeaderWidth = 200; bdCol01.ColumnTextAlignment = System.Windows.Forms.HorizontalAlignment.Left; bdCol01.DefaultSort = System.Windows.Forms.SortOrder.None; bdCol01.FormatString = "{0}"; bdCol01.PopulationType = MicroFour.StrataFrame.UI.ListViewColumnPopulationType.FormattedString; bdCol01.RegExPattern = ""; bdCol01.RegExReplacementValue = ""; // --- Add Columns to BrowseColumns Colllection // xxxx bd.BrowseResultsLayout.BrowseColumns.Add(bdCol01);
// --- 5. Create the BrowseResultsPopulationSettings MicroFour.StrataFrame.UI.Windows.Forms.BrowseResultsPopulationSettings br = new MicroFour.StrataFrame.UI.Windows.Forms.BrowseResultsPopulationSettings(); br.DisplayFieldNames.Add("Sma_name"); br.BrowseColumns.Add(bdCol01);
// --- 6. Create Search Fields MicroFour.StrataFrame.UI.Windows.Forms.SearchFieldItem SearchFieldItem1 = new MicroFour.StrataFrame.UI.Windows.Forms.SearchFieldItem(); SearchFieldItem1.AllowAdvanced = true; SearchFieldItem1.DefaultSearchStyle = MicroFour.StrataFrame.UI.BrowseDialogAllSearchTypes.BeginsWith; SearchFieldItem1.EnumType = ""; SearchFieldItem1.FieldLabelText = "Name"; SearchFieldItem1.FieldMask = ""; SearchFieldItem1.FieldName = "Sma_name"; SearchFieldItem1.FieldType = System.Data.DbType.AnsiString; SearchFieldItem1.IgnoreInitialValueIfNotVisible = true; SearchFieldItem1.InitiallyEnabled = true; SearchFieldItem1.InitialValue = ""; SearchFieldItem1.Key = "Sma_name"; SearchFieldItem1.OverrideFieldType = false; SearchFieldItem1.PopulationDataSourceSettings = null; SearchFieldItem1.SecurityKey = ""; SearchFieldItem1.TextMaskFormat = System.Windows.Forms.MaskFormat.ExcludePromptAndLiterals; SearchFieldItem1.TimeAction = MicroFour.StrataFrame.UI.BrowseDialogDateTimeAction.DoNotChangeTime; SearchFieldItem1.TopMostText = "<Not Used>"; SearchFieldItem1.TopMostValue = "-1"; SearchFieldItem1.Visible = true;
// --- 7. Add SearchField to SearchFields collection bd.SearchFields.Add(SearchFieldItem1); bd.BrowseResultsLayout = br;
// --- 10. Call up the Browse Dialog bd.ShowDialog(true);
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
Check that you set the FieldType correctly. This must match the type of defined in the BO for the field. Look in the BO designer file, in the shared/static constructor for the definition of the _FieldDbTypes values. This is the line of code that likely is causing the issue:
SearchFieldItem1.FieldType = System.Data.DbType.AnsiString;
Likely the type is DbType.String.
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
I changed to DbType.String but it did not make any difference.
After some additinal testing, the only thing I noticed was that in my SearchFiledItem1, I had called the Field Sma_Name whereas in the business object it was called SMA_NAME. I changed the SearchFiledItem1 to SMA_NAME and it fixed the problem. It obviously looks for an exact match and is case sensitive. Being used to VFP, Case Sensitivity was never an issue so I'l just have to be a bit more careful in future.
Anyway, I think I am where I wanted to be with this.... able to programatically create and call the BrowseDialog, albit for one field. I need to do some more paramerisation but many thanks again for your very detailed and 'patient' assistance
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
No problem. I had forgot that dictionaries are by default case sensitive. Sorry I didn't catch that earlier and I'm glad you got it working.
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
I am having a problem setting a property of the Browse programatically. The default browse window that comes up for the conteants is too small and I want to make it biogger:
In design mode, I can change the height (or where the BottomPanel starts). i.e. where the reulsts are shown. This seems to be in a property called BottomPanelContents , but I dont know how to access this: e.g Heght or starting position
bd.FormLayout.BottomPanelContents ???
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
|
|
|
Ivan George Borges
|
|
Group: StrataFrame MVPs
Posts: 1.9K,
Visits: 21K
|
Hi Gerard. Have you tried dealing with the FormLayout property? Also, don't forget you can give your user the ability to make it any size and save the data to a Registry Key:
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Yes I tried to use the FormLayout proerty but could not find a property like Size, or Position . For the formlayout.BottomPanel(or TopPanel) It hust seems to have Compare/Equals...Tostring. I have attached a screenshot.
|
|
|
Ivan George Borges
|
|
Group: StrataFrame MVPs
Posts: 1.9K,
Visits: 21K
|
Have you tried having a look at a BD resource file (its .resx) and checking how the layout is set?
|
|
|
Ger Cannoll
|
|
Group: StrataFrame Users
Posts: 430,
Visits: 507
|
Where would I find the BD resource file and what should I be looking for (Dont really know waht a resource file is)
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
When you adjust the form layout there are several things you can do:
- Decide where to put the three key elements of a BD: criteria, results and info panel. You have three places you can put them: top panel, bottom panel or side panel. - You decide if the user can resize the BD. And you can set the size by simply resizing the formlayout dialog that opens. - You can initially show the bottom panel or side panel.
I highly recommend that you make a little sample app so you can play around with the settings to see what they do and spark your imagination. Remember you can look at the designer file to see how to programatically setup the BD.
As to resource files, they usually are under files they are associated with. They contains things like position of a component on the design surface (design time) and icons/images/other resources that are embedded directly in a file. They are an XML file and VS has a UI to manipulate them and/or does it automatically when you move a component on the design surface or set an image on a control and use a local resource.
|
|
|
Ivan George Borges
|
|
Group: StrataFrame MVPs
Posts: 1.9K,
Visits: 21K
|
Hi Gerard. Did I say resource file?! And by that you didn't understand Designer file?  Sorry about it, I meant the .Designer.vb file. Do you still have the LookUpControlSample I posted for you? You could use it to play around with as Greg mentioned. You can play with the FormLayout and have a look at the CustomersBrowseDialog.Designer.vb and check the properties that set widths, sizes and so on: ' 'CustomersBrowseDialog ' BrowseColumnItem1.ColumnHeaderText = "First Name" BrowseColumnItem1.ColumnHeaderWidth = 200 BrowseColumnItem1.ColumnTextAlignment = System.Windows.Forms.HorizontalAlignment.Left BrowseColumnItem1.DefaultSort = System.Windows.Forms.SortOrder.None BrowseColumnItem1.FormatString = "{0}" BrowseColumnItem1.PopulationType = MicroFour.StrataFrame.UI.ListViewColumnPopulationType.FormattedString BrowseColumnItem1.RegExPattern = "" BrowseColumnItem1.RegExReplacementValue = "" BrowseColumnItem2.ColumnHeaderText = "Last Name" BrowseColumnItem2.ColumnHeaderWidth = 200 BrowseColumnItem2.ColumnTextAlignment = System.Windows.Forms.HorizontalAlignment.Left BrowseColumnItem2.DefaultSort = System.Windows.Forms.SortOrder.None BrowseColumnItem2.FormatString = "{1}" BrowseColumnItem2.PopulationType = MicroFour.StrataFrame.UI.ListViewColumnPopulationType.FormattedString BrowseColumnItem2.RegExPattern = "" BrowseColumnItem2.RegExReplacementValue = "" BrowseResultsPopulationSettings1.BrowseColumns.AddRange(New MicroFour.StrataFrame.UI.Windows.Forms.BrowseColumnItem() {BrowseColumnItem1, BrowseColumnItem2}) BrowseResultsPopulationSettings1.DisplayFieldNames.AddRange(New String() {"cust_FirstName", "cust_LastName"}) Me.BrowseResultsLayout = BrowseResultsPopulationSettings1 Me.BusinessObjectType = "LookUpControlSample_BO.CustomersBO" BrowseDialogLayoutSettings1.AllowFormResize = True BrowseDialogLayoutSettings1.BottomPanelContents = MicroFour.StrataFrame.UI.BrowseDialogLayoutType.BrowseResults BrowseDialogLayoutSettings1.FormSize = New System.Drawing.Size(833, 636) BrowseDialogLayoutSettings1.LeftSplitterDistance = 153 BrowseDialogLayoutSettings1.ShowBottomPanel = True BrowseDialogLayoutSettings1.ShowSidePanel = False BrowseDialogLayoutSettings1.SidePanelContents = MicroFour.StrataFrame.UI.BrowseDialogLayoutType.InformationPanel BrowseDialogLayoutSettings1.SideSplitterDistance = 450 BrowseDialogLayoutSettings1.TopPanelContents = MicroFour.StrataFrame.UI.BrowseDialogLayoutType.SearchFields Me.FormLayout = BrowseDialogLayoutSettings1
|
|
|
Greg McGuffey
|
|
Group: Forum Members
Posts: 2K,
Visits: 6.6K
|
I wondered what you were talking about....
|
|
|
Ivan George Borges
|
|
Group: StrataFrame MVPs
Posts: 1.9K,
Visits: 21K
|
On times like this just hit me on the head so I come back to normal...
|
|
|