New Visual Studio 2010 WinForms C# project and imported existing form containing IG 2009 controls, which were updated to NetAdvantage 2011.
Our practice and existing code would always first our UltraCombo's datasource = null; before setting the datasource = datatable object returned from a SQL procedure call.
I was shocked to see that if the UltraCombo was already bound to a datatable, the calling of the same method to set a datasource is firing the RowSelected event of the combo when combo.datasource = null; is executed!
Needless to say, this is wreaking havoc in the project and we're looking for direction.
Is this a bug or something new in 2011??
Thanks!
The take-away from this is that customers who were able to use UltraDropDown controls as DropDownLists and the .Value property outside of a grid like we did in version 9.2 will run into trouble when updating their project to a more recent version. The conversion does not error and the application compiles but throws unmanaged code exception. It was only when I added a 2011.2 version of the UltraDropDown did I realize it truly is now only meant to be used within a grid control. The control tip text even states this fact. We just happened to be victims of a not so common implementation of this control.
In DropDownList style, it makes sense for the Combo to fire the RowSelected event when you clear the data source. It has to do this, because in DropDownList style, the Value of the control cannot contain a value that is not on the list. In other words, only values on the list are valid selections. So if the Combo has a value (non-null) and you set the DataSource to null, there will be no items on the list and therefore the Value of the control changes to null and the selected row is also set to null.
Regarding UltraDropDown, this control is intended for use with some other control like the WinGrid. It has no Value property on it - it uses the Value of whatever it is attached to (the grid cell). So the error you mention here is correct.
The error is reproducible creating two new 2011.2 UltraCombo controls, setting the DropDownStyle to DropDownList, and using the exact same code I posted above. I do not get the error setting the DropDownStyle to DropDown on the converted controls or the new controls. The question is why?
Think I am on to something with the new UltraDropDown. I added two drop downs to the same form and copied the code posted above into the same events. The application will not compile! The new drop downs "do not contain a definition for 'Value'". The conversion from 9.2 to 2011.2 is allowing this code but is failing during runtime.
The same thing again, this time with an existing VS 2008 C# project after its IG 2009.1 controls were updated to the latest 2011.2. This time only two UltraCombo controls cmbA and cmbB.
Chain of events:
private void cmbA_RowSelected(object sender, RowSelectedEventArgs e) { ChangeFocus(); // simply sets focus to the status bar this.cmbA.Refresh(); if (cmbA.Value != null) { ShowHideDropDowns(); } }
private void ShowHideDropDowns() { switch (this.cmbA.Text.ToUpper()) { case "A": LoadDropDown("cmbSectorL2", "mySQLStoredProcedureA", null); this.cmbB.Visible = false; break; case "B": LoadDropDown("cmbB", "mySQLStoredProcedureB", null); this.cmbB.Visible = true; break; default: break; } }
private void LoadDropDown(string dropdownName, string spName, SqlParameter[] sqlparm) { DataSet ds = null; SqlParameter[] sqlParms = null; switch (dropdownName) { case "cmbA": if (this.cmbA.DataSource == null) { sqlParms = new SqlParameter[] { new SqlParameter("@Parm1", 2) }; ds = _mySQL.GetDataSet(_settings.myConnectionString, spName, "Data", sqlParms); this.cmbA.DataSource = ds; this.cmbA.ValueMember = "Value"; this.cmbA.DisplayMember = "Display"; } break; case "cmbB": sqlParms = new SqlParameter[] { new SqlParameter("@Parm1", this.cmbA.Text) }; ds = _mySQL.GetDataSet(_settings.myConnectionString, spName, "Data", sqlParms); this.cmbB.DataSource = null; this.cmbB.DataSource = ds; this.cmbB.ValueMember = "Value"; this.cmbB.DisplayMember = "Display"; break; default: break; } }
private void cmbB_InitializeLayout(object sender, InitializeLayoutEventArgs e) { e.Layout.Bands[0].ColHeadersVisible = false; e.Layout.Bands[0].Columns["Value"].Hidden = true; }
That's everything.
Internal error: can't convert to Destination Value.
************** Exception Text **************System.Exception: Internal error: can't convert to DestinationValue. at Infragistics.Win.EmbeddableEditorBase.GetDataFilteredDestinationValue(Object sourceVal, ConversionDirection direction, EmbeddableEditorOwnerBase owner, Object ownerContext) at Infragistics.Win.UltraWinGrid.UltraCombo.get_Value() at Infragistics.Win.UltraWinGrid.UltraGridComboEditorOwner.GetValue(Object ownerContext) at Infragistics.Win.EmbeddableEditorBase.GetDataFilterSourceValue(ConversionDirection direction, EmbeddableEditorOwnerBase owner, Object ownerContext) at Infragistics.Win.EmbeddableEditorBase.GetDataFilteredDestinationValue(ConversionDirection direction, Boolean& isValidConversion, EmbeddableEditorOwnerBase owner, Object ownerContext) at Infragistics.Win.EmbeddableEditorBase.GetDataFilteredDestinationValue(ConversionDirection direction, EmbeddableEditorOwnerBase owner, Object ownerContext) at Infragistics.Win.EditorWithCombo.GetElementValue(EmbeddableUIElementBase element) at Infragistics.Win.EditorWithCombo.GetElementText(EmbeddableUIElementBase element, Boolean ignorePasswordChar) at Infragistics.Win.EditorWithTextUIElement.PositionChildElements() at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.VerifyChildElements(ControlUIElementBase controlElement, Boolean recursive) at Infragistics.Win.UIElement.DrawHelper(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean clipText, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics) at Infragistics.Win.UIElement.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Boolean forceDrawAsFocused, Boolean preventAlphaBlendGraphics) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize, Boolean preventAlphaBlendGraphics) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode, Size elementSize) at Infragistics.Win.ControlUIElementBase.Draw(Graphics graphics, Rectangle invalidRectangle, Boolean doubleBuffer, AlphaBlendMode alphaBlendMode) at Infragistics.Win.UltraControlBase.OnPaint(PaintEventArgs pe) at Infragistics.Win.UltraWinGrid.UltraCombo.OnPaint(PaintEventArgs e) at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer, Boolean disposeEventArgs) at System.Windows.Forms.Control.WmPaint(Message& m) at System.Windows.Forms.Control.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)
...and a big red X graphic appears in place of cmbB.
Again, the only thing that happened was converting the controls from 9x to 2011.2. This code does not error before the conversion.