Skip to main content
Home Forums Silverlight Programming Report a Silverlight Bug Combobox databind error: Sys.InvalidOperationException: Managed RuntimeError error #4004 in control 'ctl02'
21 replies. Latest Post by burt52 on July 10, 2009.
(0)
marfei
Member
1 points
5 Posts
10-23-2008 7:55 PM |
Hi!
I know that they are already some posts belonging to this topic but I get the error altough I used the described work around (http://silverlight.net/forums/p/31339/99165.aspx#99165).
The error occurs in the following case:
- Bind some data to the dropdown (comboBox.ItemSource = itemList;)
- Change the selected index via the ui (select another item with the mouse)
- Clear the dropdown and bind new data (comboBox.ItemSource = null; comboBox.ItemSource = itemList;)
Allthough I use the "UpdateLayout()" Statement as described in the other post, I get the following error:
Sys.InvalidOperationException: ManagedRuntimeError error #4004 in control 'ctl02': System.ArgumentException: Value does not fall within the expected range. at MS.Internal.XcpImports.MethodEx(IntPrtr [...].
The Problem don't occurs when I bind the data only at the beginning. But since the data in the dropdown changes during the application lifecycle I had to rebind the data.
Are there any known solutions to fix this problem? Any help would be greatly appreciated!
Best regards,
Marko
ken tucker
All-Star
16332 points
2,497 Posts
10-23-2008 9:57 PM |
You should not have to clear the list before setting the new itemsource to a new list. Try removing the itemsource=null line of code and see if you still get the error.
10-24-2008 4:40 AM |
Thank you very much for the answer, but unfortunately it don't solves my problem. Although I removed the referenced line from my code the error still occures. My code now looks something like this (it's an extension method which binds the data to the dropdown):
public static void FillData<T>( this System.Windows.Controls.ComboBox comboBox, IEnumerable<T> dataSource, bool emptyEntry, string emptyEntryResource, string emptyEntryValue, string valueField, string textFieldFormatString, params string[] textField) { Type dataType = typeof(T);
string resultTextField;
List<Item> itemList = new List<Item>();
foreach (T item in dataSource) { resultTextField = textFieldFormatString;
for (int i = 0; i < textField.Length; i++) {
// determine the value and the text field [...]
} // for
itemList.Add(new Item() { Value = dataType.GetProperty(valueField).GetValue(item, null).ToString(), Name = resultTextField });
} // foreach
if (emptyEntry) { itemList.Insert(0, new Item { Value = emptyEntryValue, Name = emptyEntryResource.FromResource() }); } // if
comboBox.ItemsSource = itemList; comboBox.DisplayMemberPath = "Name";
comboBox.UpdateLayout();
if (comboBox.Items.Count > 0) { comboBox.SelectedIndex = 0; } // if
} // method Fill
After I called this method a second time for the same combobox the exception is thrown. I hope there is any other solution for my problem.
Thanks in advance und best regards,
Yi-Lun L...
25052 points
2,747 Posts
10-27-2008 3:35 AM |
Hello, can you share a sample project? Your method seems to work fine for me... While I don't know your purpose, this works fine:
{
}
source.Add(
cb.FillData<
The above code is executed each time I click a Button. I didn't see any exceptions. Of course all items are displayed as "Age", since this is how your code is written...
andulvar
155 points
102 Posts
11-04-2008 11:16 PM |
I'm having the same problem. As soon as I press the drop-down button on the ComboBox, after having changed the contents of the underlying ItemSource, I get a similar exception 4004.
This error only occurs if the underlying item source is a class and I use either DisplayMemberPath or ItemTemplate to extract the property of each item for display. If I never press the drop-down button on the ComboBox, I do not see the exception. I can see in the ComboBox selection field that the data has updated - I can see the first element in my ItemSource in the selection field.
Giganoid
24 points
16 Posts
11-05-2008 7:29 AM |
I can confirm this error!
And i've build a little sampe to analyse this error. It's not exactly the same "in control 'ctl02'"-Error that i get in my big Application but it seems to be the same root.
XAML:
<UserControl x:Class="SilverlightErrorTest.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Grid x:Name="LayoutRoot" Background="White"> <TextBlock Height="Auto" HorizontalAlignment="Left" Margin="0,18,0,0" VerticalAlignment="Top" Width="Auto" Text="Step1: Change the ComboboxItem" TextWrapping="NoWrap"/> <Button HorizontalAlignment="Left" Margin="0,100,0,0" VerticalAlignment="Top" Content="Step2: Click this Button" Click="Clicked" /> <TextBlock HorizontalAlignment="Left" Text="Step3: Try to Change the ComboboxItem again" TextWrapping="NoWrap" d:LayoutOverrides="Height" VerticalAlignment="Top" Margin="0,150,0,0"/> </Grid></UserControl>
C#:
InitializeComponent();
_ComboBox.ItemsSource = _Items;
LayoutRoot.Children.Add(_ComboBox);
LayoutRoot.Children.Remove(_ComboBox);
_ComboBox =
11-05-2008 7:58 AM |
Hi Yi-Lun,
sorry for don't answering your last question for such a long time. First of all, thank you for the reply. Since the code I've send with my last post is only a part from a large project, I'm not able to present a sample project. Unfortunately I haven't found a solution for my problem yet. I tried serveral work arounds but none of them did really work. I figured out that the error don't occures in a deterministic way, because sometimes the exception is thrown already after the second "refill" and sometimes the error don't occurs until the third or fourth "refill".
Perhaps with the provided sample project from Giganoid, we're able to find a solution for the problem.
Thanks in advance,
jregehr
13 points
14 Posts
11-06-2008 3:26 PM |
I had a similar issue with a combobox. I'd been stumped on it for a few days, especially because the stack trace was in .Net framework code and didn't reference my code at all. The hint that pointed me in the right direction was "Value does not fall within the expected range".
As it turns out, the issue is one of timing. If the itemsSource is changed right before any UI portion of the combobox is manipulated it causes the problem. For example the code below will cause the error. I believe it has to do with the time (read: latency) taken by the layout system to update the visuals on the ComboBox and its associated itemsControl, vs. the lack of time (read: immediacy) between when the ItemsSource is changed and the SelectedItem is assigned.
myComboBox.ItemsSource = {some list}myComboBox.SelectedItem = {some member of the above list}[immediate UI crash]
I also found a pretty easy way around it. Apply an empty list to the ComboBox.ItemsSource as the combobox is created or the visual is initialized. Then, add items into the list. That seems to trigger the layout manager to behave differently than if a new collection is applied to the ItemsSource. For example, the code below executes successfully. It's important to use the ObservableCollection for the combobox items to update automagically.
// using System.Collections.ObjectModel.ObservableCollection;ObservableCollection myList = new ObservableCollection();myComboBox.ItemsSource = myList // the list may or may not be empty, but it is important to assign it here... execution returns to the user thread, the layout updates, and user interaction fires ...myList.Add({some object}); // the collection notifies the combobox it has new item(s).myComboBox.SelectedIndex = {some Object};myComboBox.InvalidateMeasure(); // unnecessary, but helpful, especially if the list was empty before the line above.
// using System.Collections.ObjectModel.ObservableCollection;ObservableCollection myList = new ObservableCollection();myComboBox.ItemsSource = myList // the list may or may not be empty, but it is important to assign it here
... execution returns to the user thread, the layout updates, and user interaction fires ...
myList.Add({some object}); // the collection notifies the combobox it has new item(s).myComboBox.SelectedIndex = {some Object};myComboBox.InvalidateMeasure(); // unnecessary, but helpful, especially if the list was empty before the line above.
Let me know if you have any questions, and please mark this as the solution if it works for you.
Thanks,
- Jonathan Regehr
11-07-2008 2:12 PM |
Hi Jonathan,
i've integrated your idea in my sampe above. But it didnt worked. I saw only empty Items in the Combobox. Can you do it better? The problem is to bind "old" items to a new instance of a Combobox.
XAML: (the same)
_ComboBox.ItemsSource = _UsedItems;
_UsedItems.Add(m_Item);
_UsedItems.Clear();
Pistachi...
2 points
1 Posts
11-08-2008 1:45 AM |
I've been messing with the same problem for the last few hours, but without doing any data binding. I can recreate it with the following example:
page.xaml:
<UserControl x:Class="ComboBoxTest.Page" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Width="400" Height="300"> <Grid x:Name="LayoutRoot" Background="Blue"> <Button x:Name="btnShowDialog" Content="Show Dialog" Width="120" Height="20" Click="btnShowDialog_Click"/> <StackPanel x:Name="MyDialog" Width="200" Height="100" Orientation="Vertical" Background="Green" Visibility="Collapsed"> <ComboBox x:Name="cbxStuff" Width="150" /> <Button x:Name="btnOk" Content="Ok" Width="40" Click="btnOk_Click" /> </StackPanel> </Grid></UserControl>
page.xaml.cs:
using System;using System.Net;using System.Windows;using System.Windows.Controls;using System.Windows.Input;
namespace ComboBoxTest{ public partial class Page : UserControl { public Page() { InitializeComponent(); }
private void btnShowDialog_Click(object sender, RoutedEventArgs e) { cbxStuff.Items.Clear(); cbxStuff.Items.Add("Stuff"); cbxStuff.Items.Add("More Stuff"); cbxStuff.SelectedIndex = 0; cbxStuff.UpdateLayout(); MyDialog.Visibility = Visibility.Visible; }
private void btnOk_Click(object sender, RoutedEventArgs e) { MyDialog.Visibility = Visibility.Collapsed; } }}
It starts off just showing a button. Press the button to show the dialog (which has a combobox, and a button which hides the dialog).
If you just press the buttons, showing and hiding the dialog, the error does not occur. If, however, you:
1) Press the button to show the dialog (dialog appears)2) Interact with the combobox in any way3) Press the button to hide the dialog (dialog disappears)4) Press the button to show the dialog (Error occurs)
Error always seems to happen at the 'MyDialog.Visibility = Visibility.Visible' line.
Now, if you change the btnShowDialog_Click() method to the following:
private void btnShowDialog_Click(object sender, RoutedEventArgs e) { cbxStuff.Items.Clear(); cbxStuff.Items.Add("Stuff"); cbxStuff.Items.Add("More Stuff"); MyDialog.Visibility = Visibility.Visible; cbxStuff.UpdateLayout(); cbxStuff.SelectedIndex = 0; }
then the error no longer occurs. Strange. Seems the control misbehaves when hidden, but acts as expected when visible.
11-11-2008 10:26 AM |
Giganoid, if you're seeing empty items, be sure to set the DisplayMemberPath on the combobox to a member of the objects contained in the list that you're using as the backing collection for the ComboBox ItemsSource.
For example (code shortened for readability)
public class Person {
public string Name { get; set; }public string Address { get; set; }// other stuff left out
List<Person> people = new List<Person>();
ComboBox cb = new ComboBox {
ItemsSource = people,DisplayMemberPath = "Name"
// Add stuff to the list and it should show up in the combobox.
Let me know if you have more questions.
- Jonathan
11-11-2008 2:26 PM |
@Jonathan
In my ComboBoxItems are complex objects with texts, images (relative to the text) and sometimes different colors.
What is the correct value for DisplayMemberPath in this case? Is there any chance to solve such a problem with a DisplayMemberPath-Expression?
11-11-2008 2:52 PM |
@Giganoid
If you're using complex items are you using the ComboBox.ItemTemplate element to style the combobox items? If so you shouldn't need the DisplayMemberPath attribute for your combobox.
You should just be able to set ComboBox.ItemsSource = [instanceOfObservableCollection] once and from then on just mess with (add/remove items) the ObservableCollection object instance - the combobox should stay in sync.
kellywhite
4 points
2 Posts
11-30-2008 10:43 PM |
I also am still receiving this error, and I'm also showing/hiding the usercontrol which displays the combobox. Changing the code to use an ObservableCollection<ComboBoxItem> does not get rid of this error.
11-30-2008 10:50 PM |
I used the workaround from the link mentioned in the first post of this thread and am no longer experiencing this error. Besure to call UpdateLayout()
List<ComboBoxItem> itemList = new List<ComboBoxItem>(); ComboBoxItem selectedItem = null; foreach (var p in AllProjectsData.Projects.Where(p => p.Status == status)) { ComboBoxItem item = new ComboBoxItem(); item.Content = p.Name; item.DataContext = p; itemList.Add(item);
if (projectId == p.Id) selectedItem = item; } projectList.ItemsSource = itemList; projectList.UpdateLayout();
Urieal
14 points
7 Posts
12-02-2008 8:52 AM |
kellywhite:I used the workaround from the link mentioned in the first post of this thread and am no longer experiencing this error. Besure to call UpdateLayout()
This worked for me as well. However, I call UpdateLayout() prior to explicitly changing my SelectedIndex...
eg
uxComboBox.UpdateLayout(); uxComboBox.SelectedIndex = i + 1;
surrounded
15 points
47 Posts
01-05-2009 8:59 AM |
Just to add to this link.
Recently, I ran into the same issue documented in this link. The suggestions did not work. The way I resolved it was as follows:
I am adding comboboxes to a stackpanel, which is added to a border, which is added to a popup window. I have a case statement which allows the user to select a section, township, and range (STR), each from a separate combobox, and zoom to it. In order for the user to be able to execute more than one zoom (ie. go back and chose a different STR) I had to create the comboboxes new each time; such as pCombobox = new combobox();. While I use UpdateLayout(), it seems to have no effect - I can comment it out and get the same results.
chris69nz
6 points
3 Posts
01-21-2009 3:56 PM |
The suggestions also don't work for me. Only real solution was to remove the combobox from visual tree completely and re-add in later on once the data is re-populated. Using observablecollection and calling UpdateLayout didn't work. Therefore I think there are several bugs that cause this error.
I get the exact same error in this situation which I haven't been able to resolve at all: If the user has the drop down open, the web service call comes back and updates the list, the error occurs. I've tried setting IsDropDown to false before updating the itemssource, calling UpdateLayout, all without any luck.
My overall impression of the combobox is that it is really buggy and not ready for actual use unless you have a really simple use for it. Messing around with the visual tree to work around bugs destroys productivity and using MVVM pattern. I've had to rewrite a lot of code (based on WPF) just to avoid bugs with this control.
These bugs and the tooltip bug (https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=387409) really makes me consider suspending SL development until its ready for primetime, as they're almost showstoppers. I really hope they fix them asap and send updates out.
Mobolo
04-30-2009 6:31 PM |
In case it helps anyone else....
I had this issue with a combo box that was dynamically created in a datagrid. The DataGrid has it's own problem with selected rows dissapearing (or blanking out rather). The fix for that also solved this issue, after setting the ItemSource of the grid, call YourGrid.Focus();
PaxTerminus
05-13-2009 10:31 AM |
Yes, so far the "brute force" solution is the only one that works. I keep my combo-box in canvas and than remove it from the children collection and add a new combo-box in its place. At least all the event subroutines and references work as long as the name is the same (so the program can be coded as if it was the same combo box and intelli-sense works as it should).
With the new object method it seems that the update of the combo-box content through asynchronous means while the list is open works too. Of course the Selected Item value has to be stored in some other variable as well for the re-selection in the new object.
cnvProdTypePH.Children.Clear()
cbxProdType = New ComboBox
cnvProdTypePH.Children.Add(cbxProdType)
cbxProdType.ItemsSource = m_lstProductAll
cbxProdType.SelectedItem = m_lstProductAll.Item(0)
KooeeMan
06-25-2009 5:26 AM |
Calling combo.Measure(new Size(combo.ActualWidth, combo.ActualHeight) just after setting itemsSource worked for me.
burt52
20 Posts
07-10-2009 3:39 PM |
KooeeMan:Calling combo.Measure(new Size(combo.ActualWidth, combo.ActualHeight) just after setting itemsSource worked for me.
AWESOME, DUDE! I don't know why it works or why you thought of it, but you just saved my butt! Thanks!