2017-03-27 4 views
0

私はC#でWPFユーザーコントロールライブラリを開発しています。ライブラリには、ユーザーが対話するフォームがあります。フォームには3つのコンボボックス(ComboBox1、ComboBox2、ComboBox3)があります。ユーザーがcombobox1でアイテムを選択すると、コンボボックス2と3は、ユーザーの選択と一緒に行くアイテムを表示します。私は、このセットアップを持っている方法は次のとおりです。ComboboxItemアクセスがnullを返す

XAML:

string cmb1TypeString = cmbBox1.SelectedItem.ToString(); 
:この設定で

<ComboBox Grid.Column="1" Grid.ColumnSpan="2" x:Name="cmbBox_TubeType_SlabUserCtrl" Height="auto" SelectionChanged="cmbBox1_SelectedIndexChanged" x:FieldModifier="public"> 
     <ComboBoxItem>Item1</ComboBoxItem> 
     <ComboBoxItem>Item2</ComboBoxItem> 
     <ComboBoxItem>Item3</ComboBoxItem> 
</ComboBox> 

C#

if (this.cmbBox1.SelectedIndex == 0) 
{ 
    this.cmbBox2.ItemsSource = new object[] { "B01", "B02" }; 
    this.cmbBox3.ItemsSource = new object[] { "J01", "J22" }; 
} 
else if (this.cmbBox1.SelectedIndex == 1) 
{ 
    this.cmbBox2.ItemsSource = new object[] { "B21", "B22" }; 
    this.cmbBox3.ItemsSource = new object[] { "J21", "J32" }; 
} 
else if (this.cmbBox1.SelectedIndex == 2) 
{ 
    this.cmbBox2.ItemsSource = new object[] { "B31", "B32" }; 
    this.cmbBox3.ItemsSource = new object[] { "J21", "J32" }; 
} 

、私はその後、私に迷惑を与えるようで、このラインを持っています

これを実行すると、cmb1TypeStringはnullとして設定されます。しかし、デバッグ中にクラスの値を調べると、正しい値を持つように見えます。

他のことを試しながら、xamlからCombobox1のコンボボックス項目の初期化を取り出しました。 Cmb1TypeStringは、ユーザが選択した値として正しく返されます。この変更に伴い

this.cmbBox1.ItemsSource = new object[] { "Item1", "Item2","Item3"}; 

を次のように代わりに私は、クラス定義の)右のInitializeComponent(後のアイテムの初期化を置きます。なぜこれが起きているのか分かりません。コンボボックスの項目がxamlとコードで設定されている場合、コンボボックスの項目の扱いに違いはありますか?

お願いします。

答えて

0

それはあなたが尋ねたものを私のために100%明確ではないのですが、私は何を記述していることは事実であると思うことはできませんToString()ComboBoxItem(それはすべきではないけれどもnullのいずれか)

私の仮説を検証するためにしてください代わりに次のコード行を使用してください。

string cmb1TypeString = cmbBox1.SelectedItem.Content.ToString(); 

変更があるかどうかを確認してください。

+0

私はあなたの提案をしようとします:あなたはあなたのSelectionChangedイベントハンドラでそれらにアクセスしようとする前に、必ず要素が実際に初期化されていることを確認すべき理由

がそれです。明確にするために、コードの後半で私は 'string cmb2TypeString = cmbBox2.SelectedItem.ToString();'というステートメントを使用します。これにより、ユーザーが選択した値が正しく返されます。cmbBox1とcmbBox2/cmbBox3の唯一の違いは、最初のアイテムがxamlで初期化され、2番目と3番目のアイテムがcmbBox1のユーザー入力に基づいて動的に初期化される点です。 – snkp

0

なぜこのようなことが起こっているのかわかりません。

InitializeComponent()方法は、XAMLファイルへのURIを検索し、基本的に、あなたのXAMLマークアップで定義されている要素のインスタンスを作成しますSystem.Windows.Application.LoadComponent()メソッドに渡し:

What does InitializeComponent() do, and how does it work in WPF?

このメソッドが返される前に、どの要素にもアクセスしないでください。 ComboBoxSelectionChangedイベントのイベントハンドラをXAMLに接続した場合、すべてのComboBox要素が初期化される前に、このイベントハンドラが呼び出されることがあります。

if(cmbBox1 != null && cmbBox1.IsLoaded) //<-- 
{ 
    string cmb1TypeString = cmbBox1.SelectedItem.ToString(); 
} 
+0

OK。それは理にかなっている。だから、私があなたのことを正しく理解しているのであれば、xamlでアイテムを初期化していて、xamlでもSelectionChangedを設定しているのでアイテムは決して初期化されません。 InitializeComponent()の直後のメインクラス定義でコンボボックスに項目を追加するのは良い方法ですか?これは問題を解決するように見えるので、プログラミングの面で優れているかどうか不思議です。 – snkp

+1

MVVMデザインパターンを学習し、コンボボックスのItemsSourceをビューモデルのコレクションプロパティにバインドすることをお勧めします。https://msdn.microsoft.com/en-us/library/hh848246.aspx – mm8