WPF ComboBox SelectedItem 动态绑定
WPF ComboBox SelectedItem dynamic binding
我想将 ComboBox 的 SelectedItem 绑定到 ViewModel 中 ObservableCollection 的特定项目。
在 ViewModel 中我有一个 ObservableCollection 属性:
Public Property SourceList As ObservableCollection(Of CustomItem)
那我有这两个习惯class
Public Class CustomItem
Public Property Code As String
Public Property Source As List(Of CustomValue)
Public Property Selection As Object
End Class
Public Class CustomValue
Public Property Id As Integer
Public Property Desc As String
End Class
XAML
中的组合框
<Border Tag="10">
<ComboBox DisplayMemberPath="Desc">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource comboSourceConverter}">
<Binding Path="SourceList"/>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType=Border}" />
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</Border>
我用来设置 ItemsSource 的转换器,它工作正常。
Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
If values(0) IsNot Nothing AndAlso values(1) IsNot Nothing Then
Return DirectCast(values(0), ObservableCollection(Of CustomItem)).Where(Function(x) x.Code = CStr(values(1))).First().Source
End If
Return Binding.DoNothing
End Function
Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
Throw New NotImplementedException
End Function
我试图为 SelectedItem 做类似的事情。
在 XAML:
<Border Tag="10">
<ComboBox DisplayMemberPath="Desc">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource comboSourceConverter}">
<Binding Path="SourceList"/>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType=Border}" />
</MultiBinding>
</ComboBox.ItemsSource>
<ComboBox.SelectedItem>
<MultiBinding Converter="{StaticResource comboSourceConverter}">
<Binding Path="SourceList"/>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType=Border}" />
</MultiBinding>
</ComboBox.SelectedItem>
</ComboBox>
转换器 return 在 ComboBox 中选择了正确的值,但是这样它会在 SourceList 属性 上引发 Set 方法,因为它是在 Multibinding 中声明为第一个路径的方法.
Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
If values(0) IsNot Nothing AndAlso values(1) IsNot Nothing Then
Return DirectCast(values(0), ObservableCollection(Of CustomItem)).Where(Function(x) x.Code = CStr(values(1))).First().Selection
End If
Return Binding.DoNothing
End Function
Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
Return New Object(){value}
End Function
手动设置绑定一切正常,但我更愿意尽可能通过转换器完成所有事情。
Dim _item As CustomItem = SourceList.Where(Function(x) x.Code = Border.Tag).FirstOrDefault()
Dim _binding = New Binding("Selection")
_binding.Mode = BindingMode.TwoWay
_binding.Source = _item
ComboBox.SetBinding(ComboBox.SelectedItemProperty, _binding)
您应该让 XAML 为您完成更多艰苦的工作。获取您的 CustomItem
一次,并绑定到它的属性,而无需大惊小怪。
<Border DataContext="{Binding SourceList[10]}">
<ComboBox
DisplayMemberPath="Desc"
ItemsSource="{Binding Source}"
SelectedItem="{Binding Selection}"
/>
</Border>
我想将 ComboBox 的 SelectedItem 绑定到 ViewModel 中 ObservableCollection 的特定项目。
在 ViewModel 中我有一个 ObservableCollection 属性:
Public Property SourceList As ObservableCollection(Of CustomItem)
那我有这两个习惯class
Public Class CustomItem
Public Property Code As String
Public Property Source As List(Of CustomValue)
Public Property Selection As Object
End Class
Public Class CustomValue
Public Property Id As Integer
Public Property Desc As String
End Class
XAML
中的组合框<Border Tag="10">
<ComboBox DisplayMemberPath="Desc">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource comboSourceConverter}">
<Binding Path="SourceList"/>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType=Border}" />
</MultiBinding>
</ComboBox.ItemsSource>
</ComboBox>
</Border>
我用来设置 ItemsSource 的转换器,它工作正常。
Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
If values(0) IsNot Nothing AndAlso values(1) IsNot Nothing Then
Return DirectCast(values(0), ObservableCollection(Of CustomItem)).Where(Function(x) x.Code = CStr(values(1))).First().Source
End If
Return Binding.DoNothing
End Function
Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
Throw New NotImplementedException
End Function
我试图为 SelectedItem 做类似的事情。 在 XAML:
<Border Tag="10">
<ComboBox DisplayMemberPath="Desc">
<ComboBox.ItemsSource>
<MultiBinding Converter="{StaticResource comboSourceConverter}">
<Binding Path="SourceList"/>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType=Border}" />
</MultiBinding>
</ComboBox.ItemsSource>
<ComboBox.SelectedItem>
<MultiBinding Converter="{StaticResource comboSourceConverter}">
<Binding Path="SourceList"/>
<Binding Path="Tag" RelativeSource="{RelativeSource AncestorLevel=1, Mode=FindAncestor, AncestorType=Border}" />
</MultiBinding>
</ComboBox.SelectedItem>
</ComboBox>
转换器 return 在 ComboBox 中选择了正确的值,但是这样它会在 SourceList 属性 上引发 Set 方法,因为它是在 Multibinding 中声明为第一个路径的方法.
Public Function Convert(values() As Object, targetType As Type, parameter As Object, culture As CultureInfo) As Object Implements IMultiValueConverter.Convert
If values(0) IsNot Nothing AndAlso values(1) IsNot Nothing Then
Return DirectCast(values(0), ObservableCollection(Of CustomItem)).Where(Function(x) x.Code = CStr(values(1))).First().Selection
End If
Return Binding.DoNothing
End Function
Public Function ConvertBack(value As Object, targetTypes() As Type, parameter As Object, culture As CultureInfo) As Object() Implements IMultiValueConverter.ConvertBack
Return New Object(){value}
End Function
手动设置绑定一切正常,但我更愿意尽可能通过转换器完成所有事情。
Dim _item As CustomItem = SourceList.Where(Function(x) x.Code = Border.Tag).FirstOrDefault()
Dim _binding = New Binding("Selection")
_binding.Mode = BindingMode.TwoWay
_binding.Source = _item
ComboBox.SetBinding(ComboBox.SelectedItemProperty, _binding)
您应该让 XAML 为您完成更多艰苦的工作。获取您的 CustomItem
一次,并绑定到它的属性,而无需大惊小怪。
<Border DataContext="{Binding SourceList[10]}">
<ComboBox
DisplayMemberPath="Desc"
ItemsSource="{Binding Source}"
SelectedItem="{Binding Selection}"
/>
</Border>