2017-04-26 1 views
3

Laissez-moi vous expliquer mon cas. J'ai le contrôle d'utilisateur de wpf dans lequel je génère dynamiquement des comboboxes. Pour ce faire, j'utilise le service de contrôle de classe à partir duquel je crée les combobox avec leurs combobox et gère également les événements de changement de sélection pour chacun d'entre eux. Everthing fonctionne bien jusqu'à ce que j'essaie d'élever le deuxième événement sur la première combobox. Il y a un problème à venir quand j'essaie d'effacer les éléments de la deuxième combobox. J'ai fait debubugg et il n'y a pas de problème avec la référence de combobox que j'ai déjà vérifiée (childCmB! = Null), mais après avoir essayé d'effacer les items de cette combobox. l'exception est levée. J'essaie de trouver de nombreux cas sur les forums mais avec succès, donc j'apprécierais toute suggestion pour résoudre ce problème.Exception de référence nulle lors de la sélection de comboboxes

Merci

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); 
     } 
    } 

} 
+1

quelle ligne exacte donne la référence nulle? – BugFinder

+0

Dans la ligne où j'essaie d'assigner la variable selectedItemId. Au cours du débogage au début, la variable selectedItemId est normalement affectée, mais quand est l'appel childCmB.Items.Clear(); le débogage est à nouveau retourné au début de la méthode, puis est levé l'exception dans la ligne de la variable selectedItemId. – itgeek

Répondre

2

Je ne suis pas sûr, mais je pense que le problème est cette ligne:

String selectedItemId = ((e.Source as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem).Uid; 

Lorsque vous supprimer des éléments de la zone de liste déroulante,

e.Source as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem) is null. Par conséquent, lorsque vous tentez d'obtenir l'ID d'un élément nul, il lève une exception.

+0

Vous avez raison, mais pour moi c'est bizarre quand j'ai fait le debug de ce processus qu'au debut, le varable est assigné sans probleme, mais apres que la variable est assignée et j'essaie d'effacer les items de childCmB, le debug revient au debut de la méthode, puis est levée exception pour la variable selectedItemId. – itgeek

+0

Lorsque vous déboguez, vous passez étape par étape et il existe une différence de temps importante entre le débogage et l'exécution. Mais je ne peux pas dire quelque chose d'exact sans déboguer votre code. Au et, si cela vous a aidé à résoudre votre problème, je suis heureux. Et si c'est le cas, vous pouvez vérifier ma réponse en tant que solution. Merci. –

2

Il n'y a pas SelectedItem lorsque vous effacez ComboBox.

Néanmoins, vous devriez toujours vérifier qu'une référence est valide avant d'essayer de l'utiliser. Donc, votre méthode devrait être implémentée quelque chose comme ceci:

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)); 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+0

Vous avez raison, après avoir validé si l'élément combobox ou combobox est valide et non nul tout fonctionne correctement. Je vous remercie. – itgeek

+0

S'il vous plaît n'oubliez pas d'accepter la réponse si votre problème a été résolu: https://meta.stackexchange.com/questions/23138/how-to-accept-the-answer-on-stack-overflow – mm8