我有一个ComboBox绑定到一组动物。从中我选择了我最喜欢的动物。我需要在绑定项上方的静态null项。我使用CompositeCollection声明它。当ComboBox被绑定时,不会选择我最喜欢的动物。我该如何解决?类似问题here但仍未解决。
观察:
我已经采用了这些措施:
完成C#代码和XAML以演示问题:
using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
namespace WpfApplication1
{
public class Animal
{
public int Id { get; set; }
public string Name { get; set; }
}
public class Zoo
{
private IEnumerable<Animal> _animals = new Animal[]
{
new Animal() { Id = 1, Name = "Tom" },
new Animal() { Id = 2, Name = "Jerry" }
};
public Zoo(int initialId)
{
FavouriteId = initialId;
}
public int FavouriteId { get; set; }
public IEnumerable<Animal> Animals { get { return _animals; } }
}
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void BindComboBox(object sender, RoutedEventArgs e)
{
// Selecting the static item by default works.
//DataContext = new Zoo(-1);
// Selecting "Jerry" by default does not work.
DataContext = new Zoo(2);
}
}
}
XAML
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1">
<Window.Resources>
<CollectionViewSource x:Key="AnimalsBridge" Source="{Binding Path=Animals}" />
<CompositeCollection x:Key="AnimalsWithNullItem">
<local:Animal Id="-1" Name="Pick someone..."/>
<CollectionContainer Collection="{Binding Source={StaticResource AnimalsBridge}}" />
</CompositeCollection>
</Window.Resources>
<StackPanel>
<Button Content="Bind" Click="BindComboBox"/>
<ComboBox x:Name="cmbFavourite"
SelectedValue="{Binding Path=FavouriteId}"
SelectedValuePath="Id" DisplayMemberPath="Name"
ItemsSource="{StaticResource AnimalsWithNullItem}"/>
</StackPanel>
</Window>
答案 0 :(得分:4)
我没有解决你的问题,而是另一种选择。我个人有专门针对每个视图的视图模型。然后,我将在视图模型上有一个属性,以根据需要添加空值。我更喜欢这种方法,因为它允许对我的视图模型进行更好的单元测试。
为您的示例添加:
public class ZooViewModel
{
.....
public IEnumerable<Animal> Animals { get { return _animals; } }
public IEnumerable<Animal> AnimalsWithNull { get { return _animals.WithDefault(new Animal() { Id = -1, Name = "Please select one" }); } }
}
神奇的组件
public static class EnumerableExtend {
public static IEnumerable<T> WithDefault<T>(this IEnumerable<T> enumerable,T defaultValue) {
yield return defaultValue;
foreach (var value in enumerable) {
yield return value;
}
}
}
然后在您的XAML中,您只需绑定到
ComboBox x:Name="cmbFavourite"
SelectedValue="{Binding Path=FavouriteId}"
SelectedValuePath="Id" DisplayMemberPath="Name"
ItemsSource="{Binding AnimalsWithNull }"/>
现在您直接绑定到源并可以正常控制绑定。另请注意,因为我们正在使用&#34; yield&#34;我们不会创建新的枚举,而只是迭代现有的列表。