私はWPFの初心者であり、ComboBoxの項目をObservableCollectionにバインドしようとしています
私はこのコードを使用しました:
XAML
<Window x:Class="comboBinding2.MainWindow"
xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
Title="MainWindow" Height="350" Width="525">
<Grid>
<ComboBox x:Name="cmbTest" ItemsSource="{Binding Path=cmbContent}" Width="200" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid>
</Window>
C#
public MainWindow()
{
cmbTest.ItemsSource = cmbContent;
cmbContent.Add("test 1");
cmbContent.Add("test 2");
InitializeComponent();
}
public ObservableCollection<string> cmbContent { get; set; }
デバッグしようとするまで、このコードでエラーは発生しません。エラーがスローされます。
TargetInvocationError
タイプ「System.Reflection.TargetInvocationException」の未処理の例外がPresentationFramework.dllで発生しました
誰かが私が間違っていることを教えてもらえますか?
現在の実装にはいくつかの問題があります。他の人が述べたように、あなたのリストは現在NULL
であり、ウィンドウのDataContext
は設定されていません。
ただし、(特にWPFを使い始めたばかりなので)MVVM
を使用して、より「正しい」方法でバインディングを行うことをお勧めします。
以下の簡単な例をご覧ください。
まず、DataContext
のWindow
を設定します。これにより、XAML
がViewModel
内のプロパティを「表示」できるようになります。
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new ViewModel();
}
}
次に、次のようなWindow's
バインディング要素をすべて含むViewModel
クラスを設定します。
public class ViewModel
{
public ObservableCollection<string> CmbContent { get; private set; }
public ViewModel()
{
CmbContent = new ObservableCollection<string>
{
"test 1",
"test 2"
};
}
}
最後に、XAML
を更新して、バインディングパスがコレクションと一致するようにします。
<Grid>
<ComboBox Width="200"
VerticalAlignment="Center"
HorizontalAlignment="Center"
x:Name="cmbTest"
ItemsSource="{Binding CmbContent}" />
</Grid>
public MainWindow()
{
InitializeComponent();
cmbContent=new ObservableCollection<string>();
cmbContent.Add("test 1");
cmbContent.Add("test 2");
cmbTest.ItemsSource = cmbContent;
}
public ObservableCollection<string> cmbContent { get; set; }
上記のコードはバインディングを使用していません。つまり、それを使用すると、Combobox's
ItemSource
をバインドする必要がなくなります。バインディングを使用したくない場合は、
First:次を使用して、CodeBehind(ViewModel)からDataContextを設定します。
this.DataContext=this;
またはXamlから:
DataContext="{Binding RelativeSource={RelativeSource Self}}">
Second:ItemSourceでバインディングを使用するItemsSource="{Binding Path=cmbContent}"
と同じように、INotifyPropertyChanged
インターフェースの使用を検討することもできます。財産
cmbContent
は何も設定していないため、nullです。エラーは実際にはNullReferenceException
だと思いますが、ビューのコンストラクターにあるため、TargetInvocationException
として表示されます。
また、ItemsSource
のComboBox
を2回設定しています(バインディングで1回、コンストラクターで1回)。あなたはそれをする必要はありません。一つを選ぶ。 (DataContext
が設定されていないため)バインディングは記述どおりに機能しないため、コードで実行するか、DataContext
をセットアップする必要があります(ナディア)。