将空项目添加到有界组合框
Add an empty item to a bounded combobox
我需要在 wpf mvvm 应用程序的有界组合框中添加一个空项,我试过了
<ComboBox TabIndex="23" Text="{Binding Specialisation}" DisplayMemberPath="refsp_libelle">
<ComboBox.ItemsSource>
<CompositeCollection >
<ComboBoxItem > </ComboBoxItem>
<CollectionContainer Collection="{Binding SpecialisationItemSource}" ></CollectionContainer>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
在我尝试添加空项之前它起作用了。
<ComboBox TabIndex="23" Text="{Binding Specialisation}" ItemsSource="{Binding SpecialisationItemSource}" DisplayMemberPath="refsp_libelle"/>
所以我需要知道:
- 我犯的错误是什么?
- 我该如何解决?
谢谢,
为什么你的方法不起作用?
你使用 {Binding SpecialisationItemSource}
,因为没有明确定义绑定的源,回退到使用目标的 DataContext
作为源 - 或者更确切地说,如果 CollectionContainer
是一个FrameworkElement
,事实并非如此。因此绑定的来源是 null
并且没有项目出现在组合中。您需要显式设置绑定的 Source
属性 才能使其正常工作(设置 RelativeSource
或 ElementName
也不起作用)。
其实即使CollectionContainer
是FrameworkElement
还是不行, 因为 CompositeCollection
不是 FrameworkElement
(甚至不是 DependencyObject
), 因此数据上下文继承将被破坏)。
如何解决?
为了使用"implicit binding",您可以在资源字典中放置一个CollectionViewSource
,并使用StaticResource
扩展名来填充集合容器:
<ComboBox>
<ComboBox.Resources>
<CollectionViewSource x:Key="Items" Source="{Binding SpecialisationItemSource}" />
</ComboBox.Resources>
<ComboBox.ItemsSource>
<CompositeCollection>
<TextBlock />
<CollectionContainer Collection="{Binding Source={StaticResource Items}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
请注意,我使用了 Collection="{Binding Source={StaticResource Items}}"
而不是 Collection="{StaticResource Items}"
- 这是因为 CollectionViewSource
类型的对象不是实际集合,并且不是 [=29= 的有效值] 属性,而绑定机制就是为了把它变成一个实际的集合。另外,我用一个空的 TextBlock
替换了一个空的 ComboBoxItem
,因为前者导致了绑定错误,我真的不喜欢看到这种情况。最终,我什至会用绑定集合的项目类型的默认值替换它。
我需要在 wpf mvvm 应用程序的有界组合框中添加一个空项,我试过了
<ComboBox TabIndex="23" Text="{Binding Specialisation}" DisplayMemberPath="refsp_libelle">
<ComboBox.ItemsSource>
<CompositeCollection >
<ComboBoxItem > </ComboBoxItem>
<CollectionContainer Collection="{Binding SpecialisationItemSource}" ></CollectionContainer>
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
在我尝试添加空项之前它起作用了。
<ComboBox TabIndex="23" Text="{Binding Specialisation}" ItemsSource="{Binding SpecialisationItemSource}" DisplayMemberPath="refsp_libelle"/>
所以我需要知道:
- 我犯的错误是什么?
- 我该如何解决?
谢谢,
为什么你的方法不起作用?
你使用 {Binding SpecialisationItemSource}
,因为没有明确定义绑定的源,回退到使用目标的 DataContext
作为源 - 或者更确切地说,如果 CollectionContainer
是一个FrameworkElement
,事实并非如此。因此绑定的来源是 null
并且没有项目出现在组合中。您需要显式设置绑定的 Source
属性 才能使其正常工作(设置 RelativeSource
或 ElementName
也不起作用)。
其实即使CollectionContainer
是FrameworkElement
还是不行, 因为 CompositeCollection
不是 FrameworkElement
(甚至不是 DependencyObject
), 因此数据上下文继承将被破坏)。
如何解决?
为了使用"implicit binding",您可以在资源字典中放置一个CollectionViewSource
,并使用StaticResource
扩展名来填充集合容器:
<ComboBox>
<ComboBox.Resources>
<CollectionViewSource x:Key="Items" Source="{Binding SpecialisationItemSource}" />
</ComboBox.Resources>
<ComboBox.ItemsSource>
<CompositeCollection>
<TextBlock />
<CollectionContainer Collection="{Binding Source={StaticResource Items}}" />
</CompositeCollection>
</ComboBox.ItemsSource>
</ComboBox>
请注意,我使用了 Collection="{Binding Source={StaticResource Items}}"
而不是 Collection="{StaticResource Items}"
- 这是因为 CollectionViewSource
类型的对象不是实际集合,并且不是 [=29= 的有效值] 属性,而绑定机制就是为了把它变成一个实际的集合。另外,我用一个空的 TextBlock
替换了一个空的 ComboBoxItem
,因为前者导致了绑定错误,我真的不喜欢看到这种情况。最终,我什至会用绑定集合的项目类型的默认值替换它。