Excluding null reference when selecting comboboxes
Let me explain my case. I have a custom wpf control in which I am dynamically generating a combobox. For this purpose I am using the Class Control Service, from which I create comboboxes with their comboboxitems and also manage the selection change event for each of them. Everthing works great until I try to raise a second event on the first combo box. The problem comes when I try to clear the elements of the second group. I disabled debubugg and there is no problem with the combobox link I already checked (childCmB! = Null) but after I tried to clear the elements of that dropdown. an exception is thrown. I am trying to find many cases in the forums, but with any success, so I would appreciate any suggestion to resolve this issue.
thank
ControlService.class:
static class ControlService
{
private static ObservableDictionary<String, System.Windows.UIElement> controls = new ObservableDictionary<String, System.Windows.UIElement>();
private static Grid expanderContent;
public static Expander createExpander(String header, String name, String code)
{
header = manageControlName(header);
ExpanderModelView expanderModelView = new ExpanderModelView(name);
//Recieve template grid
expanderContent = expanderModelView.getExpanderContent();
//Add in static collection
Expander expander = new Expander() { Header = header };
//Code of provider service
expander.Uid = code;
expander.Name = name;
//Set up handler
expanderContent.AddHandler(System.Windows.Controls.ComboBox.SelectionChangedEvent, new SelectionChangedEventHandler(cmb_SelectionChanged));
//Insert data
expander.Content = expanderContent;
controls.Add(header, expander);
return expander;
}
public static void cleanUIElementCollection()
{
controls.Clear();
}
private static string manageControlName(string name)
{
int counter = 1;
if (controls.Count != 0)
{
foreach (String value in controls.Keys)
{
if (value.Equals(name))
{
if (name.Any(char.IsDigit))
name = name.Substring(0, name.IndexOf("("));
name = String.Format(name + "({0})", counter);
counter++;
}
}
}
return name;
}
private static void cmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Grid currentContent = sender as Grid;
String selectedItemId = ((e.Source as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem).Uid;
IEnumerable<Parameter> childCmBs = DataService.getServiceParametersByParentId((e.Source as System.Windows.Controls.ComboBox).Uid);
if (childCmBs.Any())
{
foreach (Parameter param in childCmBs)
{
try
{
System.Windows.Controls.ComboBox childCmB = currentContent.FindName(param.Key) as System.Windows.Controls.ComboBox;
if (childCmB != null)
{
childCmB.Items.Clear();
addComboBoxItems(DataService.getChildrenParameterValuesByParentId(selectedItemId), childCmB);
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(String.Format("Happen some problem during creating comboboxes: {0}", ex.Message));
}
}
}
}
public static void createComboBoxes(IEnumerable<Parameter> parameters, System.Windows.Controls.Panel panel)
{
foreach (Parameter parameter in parameters)
{
TextBlock cmbLabel = new TextBlock() { Text = parameter.Caption };
System.Windows.Controls.ComboBox cmb = new System.Windows.Controls.ComboBox() { Name = parameter.Key, Uid = parameter.ID };
panel.Children.Add(cmbLabel);
panel.Children.Add(cmb);
addComboBoxItems(parameter.ParameterValue, cmb);
}
}
public static void addComboBoxItems(IEnumerable<ParameterValue> parameterValues, System.Windows.Controls.ComboBox cmb)
{
foreach (ParameterValue value in parameterValues)
{
ComboBoxItem item = new ComboBoxItem()
{
Content = value.Caption,
Uid = value.ID,
Name = value.Key
};
cmb.Items.Add(item);
}
}
}
source to share
I'm not sure, but I think the problem is this line:
String selectedItemId = ((e.Source as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem).Uid;
When you clear the items of the dropdown list,
e.Source as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem) is null
...
so when you try to get the Uid of the null element, it throws an exception.
source to share
When erasing, ComboBox
no SelectedItem
.
However, you should always check that the link is valid before you try to use it. Therefore, your method should be implemented something like this:
private static void cmb_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
Grid currentContent = sender as Grid;
if (currentContent != null)
{
ComboBox comboBox = e.Source as ComboBox;
if (comboBox != null)
{
ComboBoxItem selectedItem = comboBox.SelectedItem as ComboBoxItem;
if (selectedItem != null)
{
String selectedItemId = selectedItem.Uid;
IEnumerable<Parameter> childCmBs = DataService.getServiceParametersByParentId(selectedItemId);
if (childCmBs != null && childCmBs.Any())
{
foreach (Parameter param in childCmBs)
{
try
{
System.Windows.Controls.ComboBox childCmB = currentContent.FindName(param.Key) as System.Windows.Controls.ComboBox;
if (childCmB != null)
{
childCmB.Items.Clear();
addComboBoxItems(DataService.getChildrenParameterValuesByParentId(selectedItemId), childCmB);
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(String.Format("Happen some problem during creating comboboxes: {0}", ex.Message));
}
}
}
}
}
}
}
source to share