StrataFrame Forum

Combobox not populating when on a SF User Control

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

By Jeff Pagley - 8/30/2007

I scanned the forum, but could not find my particular issue addressed. I have a DevX SF wrapped combobox on a SF User control.  I am programmically adding the user control to a form.  Along with the combobox I have textboxes on the control also.  The textboxes show the data from the BO object, but the combobox does not.  To make sure I was not missing something in the combobox settings and had all of the data binding setup correctly, I put the combobox and the same BO on a SF Maintenance form with the exact same settings and the combobox populates correctly.  What is going on?

Thanks!

By StrataFrame Team - 8/31/2007

Most likely, it's either the order in which you're adding the user control to the form or the ParentContainer property on the user control.  So, what you need to do is add the user control before the OnLoad (Load event) of the form and when you create and add the user control, set the ParentContainer property on the user control to the form.  Then, when the Load event fires on the form, the combo box will know to populate itself.
By Jeff Pagley - 8/31/2007

I not sure how to do what you are suggesting.  The parent form is already loaded.  Then through a control's Click event I am adding the control to the parent form.  The code is below:

Me.gcCampaignContainer.Controls.Add(uControl)

uControl.BringToFront()

uControl.Dock = DockStyle.Fill

The uControl contains the combobox and BO.

By StrataFrame Team - 8/31/2007

Aha, in that case, the ComboBox will not populate on its own.  You'll have to call Requery() on it.  So, add uControl.cbCombo.Requery() before the code that you posted and it should get you fixed.
By Jeff Pagley - 8/31/2007

Hi Ben,

This what I tried but the compiler doesn't like it.

uControl.Controls("cboClients").requery()

The compiler message is as follows:

'requery' is not a member of 'System.Windows.Forms.Control'.

By Greg McGuffey - 8/31/2007

You'll need to cast the control to a combo - DirectCast(uControl.Controls("cboClients").Requery(),ComboBox).Requery()



You'd need to replace the "ComboBox" with the actual type, something like Microfour.StrataFrame.UI.Windows.Forms.Combobox.



Alternately, you could provide a property on the user control that exposes the combobox or a method that does the requery.


By Greg McGuffey - 8/31/2007

DirectCast(uControl.Controls("cboClients").Requery(),ComboBox).Requery()






Doh...mistyped that, it should be:



DirectCast(uControl.Controls("cboClients"),ComboBox).Requery()
By Jeff Pagley - 8/31/2007

Hi Greg/Ben,

Unfortunately, the code did not work.  It throws another exception.  However, when you had mention using an method on the user control it got me to thinking.

In the user control load event, I filled the BO object and I executed the cbo.requery() method and it worked.  

As a part-time programmer and new to Strataframe, some things just don't dawn on me.  I came from the VB and MSAccess world.  So I am still trying to figure all of this .NET stuff out.  It is quite a learning curve when you don't work with this stuff all of the time. 

Oh by the way, since I have your attention.  I noticed that after I execute a BO.Save method, the BO.IsDirty property is still true.  What else do I need to do when saving the changes to BO for the IsDirty to reset to False?  I'm checking this property to make sure the end user saves his changes.

Thanks guys for helping a newbie like me.

By Greg McGuffey - 8/31/2007

Sorry about the code. I just typed it in, so I likely made a mistake.



The concept that is important here is that .NET is strongly typed. That means that the compiler will see a control as a control, even if it is a subclass of a control, like a combobox. The Controls collection is a collection of System.Control objects. A combobox is NOT a System.Control, though it inherits from it. Thus when you attempted to access a method of a combobox on the object returned from the Controls collection, it bombed, as System.Control doesn't have the Requery() method. Since you know that the object really is a combobox however, you can cast it to the correct type.



There are two ways to cast things in VB: DirectCast() and CType(). Apparently DirectCast is faster in some instances. You can cast an object to its native type, any type it inherits from or to any interface it implements. The object browser is your friend when figuring stuff like this out.



Finally, I've been using "combobox" very loosely here. Actually, you'd need to define the actual, specific type. If you were using a normal .NET combo, I believe it would be System.Windows.Forms.ComboBox. If you are using the SF combobox, it would be something like Microfour.StrataFrame.UI.Windows.Forms.ComboBox. I think there might be sub classes for devex and infragistics in SF too, in which case you'd use those specific types when casting. Again, use the object browser and intellisense to figure out exactly what type you need to cast to. At first this was a pain, but I've come to really like the strong typed approach.



I also came from mostly MS Access background, so I'm familiar with the pain of getting up to speed in .NET. After about 9 months heads down with .NET and SF I'm starting to get it BigGrin The cool thing I've found is that tasks usually easier in .NET, once you figure them out...Crazy...hence the pain! Without this forum, the pain would have been fatal Whistling



I'm glad you got it working. A property or method is often the way to go if you need to let the parent form manipulate something on the user control.


By Jeff Pagley - 8/31/2007

Greg

Thanks so much for the info.  I know I am going to have to spend more time studying the object browser and learning this stuff.  Unfortunately, my time is split between technical support and programming and so I am not able to focus for any length of time on .NET.  That is why we used Strataframe and rely heavily on the forums for help.

Also, do you know answer to the other part of my reponse concerning the BO.Save and the BO.IsDirty question?

By Greg McGuffey - 8/31/2007

Any time. I understand about limited time. You'll get it soon enough Hehe



As to the IsDirty question. My understanding is that it should be set to false after a save. I do know that it is just looking at the datatable that the BO wraps. Ben (or Trent if he's back) will have to field that one. It doesn't make any sense to me.


By StrataFrame Team - 9/3/2007

Greg is correct about the use of DirectCast vs CType in VB.  DirectCast tells the compiler to try casting the object and then check for implcit/explicit casting operators on the two types in question (the one being cast and the requested type) while CType tells the compiler to try casting it first, and then check for an implicit/explicit conversion operators, and then try the Convert.ToXXX methods for backward compatibility with old VB, so in some cases, CType is slower Smile.  Nice one Greg.

However, jjp, you're using C#, which doesn't have DirectCast or CType, it just has the cast syntax like C++:

string var = (string)someOtherVar;

or

object var = new SomeType();
((SomeType)var).SomeMethodOnThatType();

So, in C#, the casting operator is the equivalent to DirectCast (though the C# compiler will pick up on a few extra things that DirectCast won't).  There is no equivalent to CType, but since it's really meant for backward compatibility with old VB, and since the C# casting picks up on a few cases where DirectCast won't you don't really need it.

One other casting worth mentioning is the "as" (C#) / TryCast (VB):

object var = new SomeType();
SomeType var2 = var as SomeType;

Dim var As Object = New SomeType()
Dim var2 As SomeType = TryCast(var, SomeType)

It can only be used with reference types (so no value types, structures, etc.).  But, it will never throw an exception (hence the "Try" in the name) and it's extremely fast.  It will try to cast the object, and if it fails, it returns null (Nothing in VB), hence why you need a reference type since value types cannot be null.  So, if you're not absolutely positive that your object is going to be a certain type, always TryCast (as) and then test your variable on null (Nothing).  That combination is actually just as fast as casting and is much faster than testing on the type of an object before casting it.  If you use Reflector and look through the .NET DLLs, you'll see them use it all the time.

By StrataFrame Team - 9/3/2007

Oh, and I forgot jpp that in VB controls are marked with Friend (internal) while in C#, they're marked as private by default.  So, for the first sample of mine to work, you would need to change the modifier to either internal or public to see your combo box as a field directly on the form.
By Jeff Pagley - 9/4/2007

Thanks for the tip Ben.  In addition, I had an issue with the IsDirty property. See http://forum.strataframe.net/FindPost11280.aspx.

Thanks again.

By StrataFrame Team - 9/4/2007

That's strange.  The IsDirty property does not have a backing field.  Meaning that we don't store off the value anywhere.  Each time you call the get{} of the property, the CurrentDataTable of the business object is re-evaluated for dirty rows.  So, either one of the records is not being saved, or possibly, you're saving on a transaction.  If you save on a transaction, the changes do not get accepted until the transaction is comitted.  What I would check first is the return value of the Save() method.  It should return Success.  So, if it's returning CompletedWithExceptions or AbortedWithBrokenRules, the records are not actually being persisted to the database, and the business object will still be dirty.
By Greg McGuffey - 9/4/2007

Thanks for the details on casting. I'm not using the TryCast enough... BigGrin