2013-01-23 25 views
6

Mam ComboBox z DataContext zdefiniowany przy uruchamianiu aplikacji do odpowiedniego ViewModel. Chcę pobrać elementy z pliku XML, ale wybory użytkownika wiążą się z ViewModel, a ostatecznie z modelem.MVVM DataBinding

XAML:

<ComboBox x:Name="cbConnection" 
      ItemsSource="{Binding Source={StaticResource XmlConnectionList}, XPath=//ComboItem}" 
      DisplayMemberPath="Key" 
      SelectedValuePath="Value" 
      SelectionChanged="{Binding Path=DataContext.cbConnection_SelectionChanged}" 
      /> 

ale otrzymuję następujący wyjątek w czasie wykonywania:

{"Unable to cast object of type 'System.Reflection.RuntimeEventInfo' to type 'System.Reflection.MethodInfo'."}

Wiemy ViewModel jest odpowiednio ustawiona jako DataContext Okno widoku za. Co ja robię źle?

+0

Hej Sammarcow ... W jaki sposób wsiadasz? Czy to działa na końcu? – PGallagher

Odpowiedz

13

Używasz;

SelectionChanged="{Binding Path=DataContext.cbConnection_SelectionChanged}" 

Co w rzeczywistości jest wydarzeniem.

Należy powiązać własności publicznej (ewentualnie wykonawczych INotifyPropertyChanged) w ViewModel do selectedItem Własności zarządzać zmian tn wybór.

Zakładając, że okno ma DataContext, zamiast samego combobox ...

SelectedItem Oprawa Wersja:

Więc XAML byłoby coś takiego;

<ComboBox x:Name="cbConnection" 
      ItemsSource="{Binding Source={StaticResource XmlConnectionList}, XPath=//ComboItem}" 
      DisplayMemberPath="Key" 
      SelectedValuePath="Value" 
      SelectedItem="{Binding Path=DataContext.cbConnectionSelectedItem}" 
/> 

W swoim ViewModelu;

Private _cbConnectionSelectedItem As XmlElement 

Public Property cbConnectionSelectedItem As XmlElement 
    Get 
     Return _cbConnectionSelectedItem 
    End Get 
    Set(value As XmlElement) 
     If value.Equals(_cbConnectionSelectedItem) = False Then 
      _cbConnectionSelectedItem = value 
      OnPropertyChanged("cbConnectionSelectedItem") 
      End If 
    End Set 
End Property 

Tekst Oprawa Wersja:

Oczywiście, jeśli wszystkie Twoje zainteresowanie jest wartość tekstu, co oni wybrali, można teoretycznie tylko powiązać obiekt ComboBox tekst do public string Właściwość w twoim ViewModel;

Twój XAML będzie wtedy;

<ComboBox x:Name="cbConnection" 
       ItemsSource="{Binding Source={StaticResource XmlConnectionList}, XPath=//ComboItem}" 
       DisplayMemberPath="Key" 
       SelectedValuePath="Value" 
       Text="{Binding Path=DataContext.cbConnectionText}" 
    /> 

Twój model ViewModel;

Private _cbConnectionText As String 

Public Property cbConnectionText As String 
    Get 
     Return _cbConnectionText 
    End Get 
    Set(value As String) 
     If value.Equals(_cbConnectionText) = False Then 
      _cbConnectionText = value 
      OnPropertyChanged("cbConnectionText") 
      End If 
    End Set 
End Property 

SelectedValue Oprawa Wersja:

Jeśli wyświetlanie kluczem, ale chcą wartość z parę klucz/wartość, to należy wiązać z SelectedValue;

XAML;

<ComboBox x:Name="cbConnection" 
    ItemsSource="{Binding Source={StaticResource XmlConnectionList}, XPath=//ComboItem}" 
    DisplayMemberPath="@Key" 
    SelectedValuePath="@Value" 
    SelectedValue="{Binding Path=DataContext.cbConnectionValue}" /> 

ViewModel;

Private _cbConnectionValue As String 

Public Property cbConnectionValue As String 
    Get 
     Return _cbConnectionValue 
    End Get 
    Set(value As String) 
     If value.Equals(_cbConnectionText) = False Then 
      _cbConnectionValue = value 
      OnPropertyChanged("cbConnectionValue") 
      End If 
    End Set 
End Property 

Zwróć uwagę na dodatkowe symbole @.

Jak już wspomniałem powyżej, zakłada się, że w tym oknie znajduje się zestaw DataContext. Jeśli nie, usuń "DataContext" z powyższych powiązań!

Zakładam, że widzisz obecnie elementy wymienione na liście ComboBox?

Mam nadzieję, że to pomoże!

+0

Powiązanie z SelectedIndex wymagałoby innego odniesienia do źródła danych XML w ViewModelu w celu ustalenia wartości powiązanej z DisplayMEmeber, czyż nie? W przeciwnym razie będę znać tylko SelectedIndex, ponieważ ComboBox jest wypełniany z zewnętrznego źródła danych. – sammarcow

+0

Przepraszam, szybko zauważyłem, że mam na myśli Wybrany Przedmiot ... – PGallagher

+0

Hm, nie jestem pewien, co robię źle, ale "' nie wydają się ognia getter lub setter ConnectionString właściwość w ciągu mój ViewModel. – sammarcow

7

trzeba użyć wyzwalaczy zdarzeń dla ComboBox Wybór zmieniło zdarzenie Należy starać poniżej kod wzmianka

<ComboBox Margin="192,5,5,5" DisplayMemberPath="AttachmentName" ItemsSource="{Binding AttachementList, Mode=TwoWay}" Style="{StaticResource BasicComboBoxStyle}" BorderThickness="2" BorderBrush="DarkGray" 
          Name="cmb_AttchDetails" Width="287" Height="25" SelectedItem="{Binding Defaultrequiredattachment, Mode=TwoWay}"> 
        <l:Interaction.Triggers> 
         <l:EventTrigger EventName="SelectionChanged"> 
          <l:InvokeCommandAction Command="{Binding DataContext.AttachmentNameCommand,Mode=TwoWay,RelativeSource={RelativeSource AncestorType=controls:ChildWindow}}" CommandParameter="{Binding ElementName=cmb_AttchDetails,Path=SelectedItem}" /> 
         </l:EventTrigger> 
        </l:Interaction.Triggers> 
       </ComboBox> 

dla nich trzeba dodać odniesienie jak

xmlns:l="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
+0

Nie testowałem tego, ale zaakceptowana odpowiedź wydaje się skutecznie osiągnąć ten sam wynik. – sammarcow