By Ger Cannoll - 7/31/2010
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
|
By Edhy Rijo - 7/31/2010
Hi Gerard,Take a look at the StrataFlix sample application, it does have a user control class to do the kind of search you want to do and use it in several forms. Sorry I don't remember the exact reference, but I know it is there.
|
By Ivan George Borges - 7/31/2010
Hi Gerard.Here is a sample on how to deal with BrowseDialogs and LookUp controls: http://forum.strataframe.net/FindPost27794.aspx Cheers.
|
By Ger Cannoll - 8/1/2010
Many thanks for your replies. I'll have alook at theseRegards,Gerard
|
By Ivan George Borges - 8/2/2010
You're welcome, Gerard.
|
By Ger Cannoll - 8/3/2010
Hi Ivan. I have looked through the sample and am havong some difficulty just trying to understand whats going on, mainly because of my lack of experience on meaty c# projects. Obviously some of the code is generated by the framework, and some is not, and this is part of the difficulty I am having.At this stage, before I do any serious work on this, I'd like to know in principle if it is feasible to have a 'Black Box' scenario where , in my 'LookupClass' , there are no dependencies on Browse Dialogs or even a Business Object being dropped on a form. In simple terms , I would like to have say a 'TextBox' with a no. of Properties (e.g. BusinessObject I will be looking up, a subset of the browseDialog parameters to identify the style of Dialog I will be calling, and then a no. of methods where I will populate the business object). Ideally, I dont want to be dependent on any Business Objects or browse Dialogs having to be dropped on a form and want this to be a completedly self contained piece of code. i.e. By looking at the Class, everything will be in there Do you reckon doing something like this is feasible ?
|
By Ivan George Borges - 8/3/2010
Hi Gerard.Well, I would say that almost everything is possible given the amount of energy you are willing to put into the action. That is how I accomplished the task using the StrataFrame way of doing things. I guess you could create properties and methods to make it generic. I tend not to fight the framework whenever I can.
|
By Ger Cannoll - 8/3/2010
Hi Ivan. I will plough ahead then and see if I can develop a small Class. I initially wanted to ensure that this was feasible before devoting a lot of time and effort. I use these lookups all over the place , and in our VFP system, we have a few classes specificaly for this which are fairly generic and wanted to replicate something similar in SF if possible. I realise it may be a bit of work up front, but should pay off in the long run Regards, Gerard
|
By Greg McGuffey - 8/3/2010
I just took a look at the sample (nice Ivan) and then tried to "genericize" it. See the samples section for the new version of Ivan's sample that includes a couple of possible ways to make this more generic.
http://forum.strataframe.net/FindPost27814.aspx
|
By Ger Cannoll - 8/4/2010
Hi Greg.Many thanks for this and particulalrly taking the time to tease out and explain the pros and cons. I have had a quick look at it , but will need to sit down and devote some time to it, but no doubt your very detailed explanations should help a lot. Regards, Gerard
|
By Greg McGuffey - 8/4/2010
My pleasure. Let me know if you need more clarification or if you come upon another solution. Always good to learn/discover different ways of solving a problem and/or understanding all the nuances of a problem!
|
By Ger Cannoll - 8/9/2010
Hi Greg. Am working my way through a sample for a generic browse. Just a few questions at this stage (prompted after looking at your example)How do I instantiate a BO in C# Does this work: BusinessLayer bo = new BusinessLayer(); bo.Parent = "XYZ" etc On your sample, I have seen references to : BusinessLayer bo = new BusinessLayer(); bo=CType(Activator.CreateInstance............) Just not sure if I have to use CType, and if I have to use it, what is it doing ?
|
By Greg McGuffey - 8/10/2010
How do I instantiate a BO in C#
The first thing to be clear on is what you want to work with when using or creating an object. I.e. if I have a BO that inherits from the _BaseBO in the project, which in turn inherits from the SF BusinessLayer (etc.), I can work with it as the actual typed BO from my project (like CustomersBO) or as a _BaseBO or as a BusinessLayer. E.g. all of the following are valid ways to create a CustomersBO using Activator.CreateInstance:
Type boType = Common.GetTypeFromReferencedAssemblies(boTypeName);
CustomersBO custBO = (CustomersBO)Activator.CreateInstance(boType);
_BaseBO custAsBaseBO = (_BaseBO)Activator.CreateInstance(boType);
BusinessLayer custAsBusinessLayerBO = (BusinessLayer)Activator.CreateInstance(boType);
Note that Activator.CreateInstance takes a Type and then creates an object of that type, but it returns an Object. The actual type is of the specific type you create, CustomersBO in this example. I.e. in all instances in this example, the actual object returned by CreateInstance is a CustomersBO. We are just casting to a type we want to work with. As long as the object supports the cast, we're good.
In the case of this sample app, I left it as _BaseBO because in Ivan's original sample he was using the GetFieldValueByPrimaryKey method (I ended up not using this, so the _LookupBusinessObject could be changed to by of type BusinessLayer rather than _BaseBO).
Note that this sort of thing isn't of much use:
BusinessLayer bo = new BusinessLayer();
bo=CType(Activator.CreateInstance............);
The BusinessLayer object created on the first line is just created, then gets dereferenced on the next line, and thus setup for garbage collection. Either use something like I was using above or something like this:
BusinessLayer bo = null;
bo=CType(Activator.CreateInstance............);
Setting to null is not strictly necessary, but the VS compiler barks if you don't do it.
Is this starting to make more sense?
|
By Ger Cannoll - 8/10/2010
Hi Greg.I am obviously missing something fairly basic here . For instance , if I want to create a new "table" object, all I do is: DataTable dt = new DataTable();and than I can use all the properties and methods of dt Why can I not do the same for BusinessObjects i.e. BusinessLayer bo = new BusinessLayer();
|
By Greg McGuffey - 8/11/2010
First, you can do that, but in the context of this example, it doesn't get us what we want (a general solution to the lookup problem). The way the BOs work is using inheritance. I.e. the final functionality of the BO is the combination of all the classes that it inherits from plus the functionality it adds. So, if you look at the CustomersBO in object browser you'll see that is composed of (starting at the bottom, working up):
- Object: base .NET object
- MarshalByValueComponent: Provides basic component functionality, allows BOs to be used in remoting situations
- BusinessLayerBase: Provides basic BO functionality, manages bound controls, provides CopyDataFrom functionality
- BusinessLayer: Provides base BO functionality, broken rules, events, base fill methods etc.
- _BaseBO: Add the GetFieldValueByPrimaryKey method, used in Ivan's original sample
- CustomersBO: Adds meta data (table name, field info) that actually allows access to the customers table
There are two important points here:
1. You can treat the CustomersBO as any of the objects it inherits from by casting it.
2. If you want to actually access data, you need a full blow BO (that has been created by the BO Mapper). The BusinessLayer doesn't have enough functionality/meta data yet.
In the context of this sample, what we are doing is writing code that does not know the exact type of BO that will be used (e.g. it can be used with CustomersBO or OrdersBO or WidgetsBO). This requires two approaches. First we must use the Activator.CreateInstance() to create the BO. This uses reflection to create a specific type of BO, as configured via the BrowseDialog. This allows that specific BO to be used to access data from the search, without knowing what the properties are in the LookupControl. In order to interact with the BO, we need to figure out what functionality we need and then cast to the necessary object form within the BO's inheritance hierarchy. I.e. in this design, we cast the BOs to _BaseBO (though we don't actually need that functionality, just the BusinessLayer's functionality). This means that while within the LookupControl we are dealing with the _LookupBusinessObject, that is a _BaseBO the actual objects are of specific types of BOs. In the sample, it is a CustomersBO. But it could be an OrdersBO, etc.
When you know what the object is at design time, then you use the direct instantiation methods you are talking about ( CustomersBO bo = new CustomersBO; ). However, when you are programming a component/control/class that will not know the exact type it is working with until runtime, you have to use something like this. In those cases, you either pass in the exact object, which is then referenced as the necessary object type (or interface type) within the code, or you have to use reflection to create the object based on a fully qualified class name, using Activator.CreateInstance(), then cast it to the desired type.
Is this starting to make sense? Answering the right question?
|
By Ger Cannoll - 8/16/2010
Hi Greg.. Did'nt realise there was so much in Reflection so I am taking it fairly slowly now. I have just set up a button with a few liines of code. Its compliling ok but am getting a run time error: 1 string boString; 2 boString = "Kernel_BOLibrary.SmaBO"; // This is the name of one of my Business Objects 3 MicroFour.StrataFrame.Business.BusinessLayer bo = new MicroFour.StrataFrame.Business.BusinessLayer(); 4 Type oType = Type.GetType(boString,true); 5 // bo = Activator.CreateInstance(oType); Could not load type 'Kernel_BOLibrary.SmaBO' from assembly 'Kernel_App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. Runtime error on on Line 4.(All my Business objects are in the project in a DLL called Kernel_BOLibrary.DLL  I tried it without the Kernel_BOLibrary and it came up with a similar message. Also tried to input Type.GetTypeFromReferencedAssemblies but intellisense would not bring this up
|
By Greg McGuffey - 8/17/2010
Gerard,
This is actually a good way to start understanding reflection, which can be a very powerful tool.
OK, now to your issues:
- Just to be sure, you do have the Kernel_BOLibrary assembly referenced in project where this code is executing right? If not, that could cause the problem.
- You need the fully qualified type name (which you may have, I'm just double checking here). When using a string like this, the easiest way to get this done is to use the Object Browser. Simply navigate to the BO, right click on the BO and click Copy. Then paste this into your code. It will be the fully qualified type name.
- To use the Common.GetTypeFromReferencedAssemblies() method, you still need the fully qualified type name and you need to make sure the assembly containing the code includes a reference to the MicroFour StrataFrame Base.dll and you have a using statement for MicroFour.StrataFrame.Tools namespace (or use the fully qualified method: MicroFour.StrataFrame.Tools.Common.GetTypeFromReferencedAssemblies()).
- You really, really don't need to set the BO to an instance of a new BusinessLayer object. The intent of the declaration is to identify the type of the variable that you'll use. The actual instance will use a type determined at runtime. So you'd replace this:
3 MicroFour.StrataFrame.Business.BusinessLayer bo = new MicroFour.StrataFrame.Business.BusinessLayer();
with
3 MicroFour.StrataFrame.Business.BusinessLayer bo = null;
or you could replace lines 3 and 5 with a single that declares and then sets the bo variable. Using the this concept to set the BO and and the BO name string along with the GetTypeFromReferencedAssemblies you might reduce your code to:
1 string boString = "Kernel_BOLibrary.SmaBO"; // This is the name of one of my Business Objects
2 Type oType = MicroFour.StrataFrame.Tools.Common.GetTypeFromReferencedAssemblies(boString);
3 MicroFour.StrataFrame.Business.BusinessLayer bo = Activator.CreateInstance(oType);
Give this a try and see how it goes. We'll go from there....
|
By Ger Cannoll - 8/17/2010
I have Kernel_BOLibrary referenced as I can access the Business Objects no problem on other butons on the form (not using reflection) Ok. Still bogged down I'm afraid at this Gettype command. I am not sure at this stage what parameters this takes.I've tried a few permutations with various run time errors boString = "Kernel_BOLibrary.SmaBO"; // (Got by rt clicking the Business Object in Object Browser) Error--->Could not load type 'Kernel_BOLibrary.SmaBO' from assembly 'Kernel_App, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'......indicates boString = "SmaBO,Kernel_BOLibrary"; // Tried a comma between BO and the BO Library Error --->Could not load type 'SmaBO' from assembly 'Kernel_BOLibrary'. (looks like its closest to being correct as it seems to recognise the BO and the BOLibrary ??)
|
By Greg McGuffey - 8/17/2010
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.
|
By Ger Cannoll - 8/17/2010
Ok Greg.... will give that a try .
|
By Ger Cannoll - 8/17/2010
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..
|
By Greg McGuffey - 8/19/2010
I'll take a look at this either later today or tomorrow.
|
By Ger Cannoll - 8/24/2010
Hi. just wondering if this has dropped off the radar ??
|
By Greg McGuffey - 8/24/2010
Ah...oops. I'll take a look at it today. Sorry for the delay.
|
By Greg McGuffey - 8/24/2010
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 ) );
}
|
By Ger Cannoll - 8/29/2010
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);
|
By Ger Cannoll - 9/3/2010
Just wondering...any thoughts on this ??
|
By Greg McGuffey - 9/3/2010
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.
|
By Ger Cannoll - 9/8/2010
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);
|
By Greg McGuffey - 9/10/2010
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.
|
By Ger Cannoll - 9/10/2010
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
|
By Greg McGuffey - 9/14/2010
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.
|
By Ger Cannoll - 9/20/2010
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 ???
|
By Ger Cannoll - 9/27/2010
Any ideas on this ??
|
By Ivan George Borges - 9/27/2010
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:
|
By Ger Cannoll - 9/28/2010
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.
|
By Ivan George Borges - 9/28/2010
Have you tried having a look at a BD resource file (its .resx) and checking how the layout is set?
|
By Ger Cannoll - 9/28/2010
Where would I find the BD resource file and what should I be looking for (Dont really know waht a resource file is)
|
By Greg McGuffey - 9/28/2010
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.
|
By Ivan George Borges - 9/28/2010
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
|
By Greg McGuffey - 9/28/2010
I wondered what you were talking about....
|
By Ivan George Borges - 9/28/2010
On times like this just hit me on the head so I come back to normal...
|