您好我已经编写了MVVM方式的小程序来测试CollectionViewSource的用法。我有一个UserControl包含ListBox并具有依赖属性项,它将此控件中的绑定项“转发”到ListBox ItemsSource:
<UserControl x:Class="TestingCollectionViewSource.TestControlWithListBox"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:TestingCollectionViewSource="clr-namespace:TestingCollectionViewSource"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<Grid>
<ListBox ItemsSource="{Binding Items,
RelativeSource={RelativeSource AncestorType=TestingCollectionViewSource:TestControlWithListBox}}" />
</Grid>
</UserControl>
public partial class TestControlWithListBox : UserControl
{
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof (IEnumerable<string>), typeof (TestControlWithListBox), new PropertyMetadata(default(IEnumerable<string>)));
public IEnumerable<string> Items
{
get { return (IEnumerable<string>) GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}
public TestControlWithListBox()
{
InitializeComponent();
}
}
我尝试使用ObservableCollection和ViewViewSource绑定到Items。 它适用于ObservableCollection,但不适用于CollectionViewSource。
<Window x:Class="TestingCollectionViewSource.MainWindowView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:TestingCollectionViewSource="clr-namespace:TestingCollectionViewSource" Width="500" Height="500">
<Grid>
<TestingCollectionViewSource:TestControlWithListBox Items="{Binding Path=ItemsCollectionViewSource.View}"/>
</Grid>
</Window>
public class MainWindowViewModel : Screen
{
private ObservableCollection<string> items;
public ObservableCollection<string> Items
{
get { return items; }
set
{
items = value;
NotifyOfPropertyChange(() => Items);
}
}
private CollectionViewSource itemsCollectionViewSource;
public CollectionViewSource ItemsCollectionViewSource
{
get { return itemsCollectionViewSource; }
set
{
itemsCollectionViewSource = value;
NotifyOfPropertyChange(() => ItemsCollectionViewSource);
}
}
public MainWindowViewModel()
{
DisplayName = "Testing testing testing";
Items = new ObservableCollection<string>()
{
"1",
"2 2",
"3 3 3",
"4 4 4 4"
};
ItemsCollectionViewSource = new CollectionViewSource() { Source = Items};
}
}
但是如果我尝试将CollectionViewSource.View绑定到ListBox没有问题,所有列表项都包含在ListBox中,如下图所示:
这种行为可能是什么原因,是否有任何解决方案?
答案 0 :(得分:4)
要使绑定工作,源属性和目标属性应该是相同的数据类型。
如果仔细查看“输出”窗口,您将看到针对源和目标属性的不匹配数据类型记录的绑定错误。
CollectionViewSource.View
属性属于ICollectionView
类型,它继承自IEnumerable
而非IEnumerable<string>
。因此,源属性类型为IEnumerable
,而您的Items
DP属于IEnumerable<string>
类型。因此,它不起作用。
虽然它适用于ObservableCollection<string>
,因为它同时实现了IEnumerable<string>
和IEnumerable
。
从上面可以看出,所有列表都直接或间接地实现了IEnumerable
。所以,你可以做的是使你的Items
DP类型为IEnumerable而不是IEnumerable<string>
,它也适用于CollectionViewSource。
public static readonly DependencyProperty ItemsProperty =
DependencyProperty.Register("Items", typeof (IEnumerable),
typeof (TestControlWithListBox), new PropertyMetadata(default(IEnumerable)));
public IEnumerable<string> Items
{
get { return (IEnumerable) GetValue(ItemsProperty); }
set { SetValue(ItemsProperty, value); }
}