2017-04-26 9 views
3

私の場合を説明しましょう。私はコンボボックスを動的に生成するwpfユーザコントロールを持っています。この目的のために、コンボボックスをコンボボックスと一緒に作成し、それぞれのセレクション変更イベントを管理するクラスコントロールサービスを使用します。 最初のコンボボックスで2回目のイベントを開催しようとするまでは、素晴らしいことはありません。 2番目のコンボボックスの項目をクリアしようとすると、問題が発生します。私はdebubuggして、私はすでに確認したコンボボックス(childCmB!= null)の参照に問題はありませんが、後にこのコンボボックスの明確な項目を試してみてください。例外がスローされます。 私はフォーラムで多くのケースを見つけようとしていますが、成功したので、この問題を解決するための提案をお願いします。コンボボックスの選択中のNULL参照例外

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

正確な行はnull参照を与えますか? – BugFinder

+0

私は変数selectedItemIdを割り当てようとしています。最初のデバッグでは、変数selectedItemIdが通常割り当てられますが、呼び出されるのはchildCmB.Items.Clear()です。デバッグはメソッドのbegininngに戻され、変数selectedItemIdの行で例外が発生します。 – itgeek

答えて

2

私はわかりませんが、私は問題はこのラインだと思う:

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

あなたコンボボックスの明確な項目、

はあなたに

ControlService.classありがとうございました

e.Source as System.Windows.Controls.ComboBox).SelectedItem as ComboBoxItem) is null

したがって、nullアイテムのUidを取得しようとすると、例外がスローされます。

+0

私はこのプロセスのデバッグを行ったときに私は間違っていますが、最初はvarableが問題なく割り当てられていましたが、変数が割り当てられた後にchildCmBの項目をクリアしようとすると、デバッグが最初に戻ります変数のselectedItemIdに対して例外を発生させます。 – itgeek

+0

デバッグするときは、ステップバイステップで渡され、デバッグと実行の間に重要な時間差があります。しかし、あなたのコードをデバッグすることなく、何かを正確に言うことはできません。そして、それがあなたの問題を解決するのに役立つなら、私は満足しています。このような場合は、自分の回答を解決策として確認できます。ありがとう。 –

2

ComboBoxをクリアすると、SelectedItemはありません。

ただし、使用する前に参照が有効であることを常に確認する必要があります。したがって、あなたのメソッドは次のように実装されるべきです:

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

あなたは、コンボボックスまたはコンボボックスの項目が有効で、nullではないことがすべて正しく動作するかどうかを検証した後で、正しく動作します。ありがとうございました。 – itgeek

+0

問題が解決した場合は、是非回答を受け入れてください:https://meta.stackexchange.com/questions/23138/how-to-accept-the-answer-on-stack-overflow – mm8