MVVM DataBinding

sam*_*cow 6 .net data-binding wpf user-interface mvvm

我有一个ComboBox,其中DataContext在应用程序启动时定义到相应的ViewModel.我想从XML文件中获取项目,但是用户选择绑定到ViewModel,最终绑定到模型.

XAML:

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

但是我在运行时遇到以下异常:

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

我们知道ViewModel被适当地设置为View窗口的DataContext.我究竟做错了什么?

PGa*_*her 13

您正在使用;

SelectionChanged="{Binding Path=DataContext.cbConnection_SelectionChanged}" 
Run Code Online (Sandbox Code Playgroud)

这实际上是一个事件.

您应该将ViewModel中的公共属性(可能实现INotifyPropertyChanged)绑定到SelectedItem属性,以管理Selection的更改.

假设你的窗口有DataContext,而不是组合框本身......

SelectedItem绑定版本:

所以你的XAML会是这样的;

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

在你的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
Run Code Online (Sandbox Code Playgroud)

文本绑定版本:

当然,如果您感兴趣的是他们所选择的文本值,理论上您可以将ComboBox文本属性绑定到ViewModel中的公共字符串属性;

那你的XAML就是;

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

和你的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
Run Code Online (Sandbox Code Playgroud)

SelectedValue绑定版本:

如果您正在显示Key,但想要Key/Value Pair中的Value,那么您应该绑定到SelectedValue;

XAML;

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

视图模型;

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
Run Code Online (Sandbox Code Playgroud)

注意额外的@符号.

如上所述,这假设您的Window在此处设置了DataContext.如果没有,那么从上面的Bindings中删除"DataContext."!

我假设你现在看到你的ComboBox中列出的项目?

希望这可以帮助!

  • 与问题没有直接关系,但您的评论"这实际上是一个事件." 提示我检查我的XAML,我试图将一个布尔值绑定到CheckBox的"Checked"属性.'Checked'确实是一件大事!将它绑定到IsChecked而且一切都很好. (3认同)

Dha*_*tel 7

你必须使用事件触发器为comboBox选择更改事件你应该尝试下面提到的代码

<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>
Run Code Online (Sandbox Code Playgroud)

对于这些你必须添加像参考

  xmlns:l="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
Run Code Online (Sandbox Code Playgroud)