2015-02-06 5 views
2

Я новичок в WPF и пытается связать пункты в ComboBox к ObservableCollectionWPF ComboBox привязки ItemsSource

Я использовал этот код:

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

Может кто-нибудь сказать мне, что я делаю неправильно?

ответ

6

Есть несколько вещей, которые не соответствуют текущей реализации. Как указывали другие, ваш список в настоящее время 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(); 
    } 
} 

Далее, просто настроить ViewModel класс, который будет содержать все Window's обязательных элементов, таких как:

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> 
+0

Это прекрасно работает, но как я могу добавить другую строку в CmbContent из MainWindow ??? – LUXS

+0

Вы хотите добавить строку в режиме реального времени или включить combobox в дополнительные строки? –

+0

Я хочу добавить строку в реальном времени – LUXS

2
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'sItemSource, если вы wan't использовать связывание необходимо

Первый: Set DataContext от CodeBehind (ViewModel) с помощью:

this.DataContext=this; 

или из Xaml:

DataContext="{Binding RelativeSource={RelativeSource Self}}"> 

Второй: использовать Binding в ItemSource Так же, как вы делали ItemsSource="{Binding Path=cmbContent}" вы можете также considere с помощью INotifyPropertyChanged интерфейса, если вы хотите Уведомлять пользовательского интерфейса в случае каких-либо изменений в свойстве

1

cmbContent равна нулю, потому что вы никогда установите его на что угодно. Я предполагаю, что ошибка на самом деле NullReferenceException, но она отображается как TargetInvocationException, потому что она находится в конструкторе представления.

Также вы устанавливаете ItemsSource в ComboBox дважды (один раз в привязке, один раз в конструкторе). Вам не нужно это делать. Выбери один. Ваша привязка не будет работать так, как она написана (потому что DataContext не установлен), поэтому вам нужно либо пойти с этим в код, либо настроить DataContext (как предложила Надя).