Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVVM DataBinding

I have a ComboBox with the DataContext defined at application start to the appropriate ViewModel. I want to grab items from a XML file but have user selections bind to the ViewModel, and ultimately the model.

XAML:

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

but I am getting the following exception at runtime:

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

We know the ViewModel is appropriately set as the DataContext of the View's Window. What am I doing wrong?

like image 920
sammarcow Avatar asked Jan 23 '13 22:01

sammarcow


2 Answers

You are using;

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

Which is actually an event.

You should bind a Public Property (possibly implementing INotifyPropertyChanged) in your ViewModel to the SelectedItem Property to manage changes tn the Selection.

Assuming that your window has the DataContext, rather than the combobox itself...

SelectedItem Binding Version:

So your XAML would be something like;

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

And in your ViewModel;

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

Text Binding Version:

Of course, if all your interested in is the Text Value of what they've chosen, you could in theory just bind the ComboBox Text Property to a Public String Property in your ViewModel;

Your XAML would then be;

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

And your 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 Binding Version:

If you are displaying the Key, but want the Value from the Key/Value Pair, then you should bind to the 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

Note the extra @ symbols.

As I mentioned above, this assumes that your Window has the DataContext set here. If not, then remove the "DataContext."'s from the Bindings above!

I assume you're seeing items listed in your ComboBox currently?

Hope this helps!

like image 89
PGallagher Avatar answered Nov 15 '22 10:11

PGallagher


you have to use event Triggers for comboBox Selection changed Event You should try below mention code

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

for these you have to add reference like

  xmlns:l="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
like image 28
Dhaval Patel Avatar answered Nov 15 '22 09:11

Dhaval Patel