6

我有一个 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}"
          />

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

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

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

4

2 回答 2

13

您正在使用;

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

这实际上是一个事件。

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

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

SelectedItem 绑定版本:

所以你的 XAML 会是这样的;

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

在您的 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

文字装订版本:

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

您的 XAML 将是;

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

还有你的 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 绑定版本:

如果您正在显示键,但想要键/值对中的值,那么您应该绑定到 SelectedValue;

XAML;

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

视图模型;

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

注意额外的 @ 符号。

正如我上面提到的,这假设您的 Window 在此处设置了 DataContext。如果不是,则从上面的绑定中删除“DataContext。”!

我假设您目前正在查看 ComboBox 中列出的项目?

希望这可以帮助!

于 2013-01-23T22:57:49.100 回答
7

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

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

对于这些,您必须添加参考,例如

  xmlns:l="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 
于 2013-01-24T11:46:43.130 回答