绑定协方差集合WPF
本文关键字:WPF 集合 方差 绑定 | 更新日期: 2023-09-27 18:19:37
我有:
public class BaseSong
{
public string Artist
{
get; set;
}
public string Title
{
get; set;
}
public class ExtendedSong : BaseSong
{
public string Bitrate { get; set;}
...
}
public class CollectionSong<T> : ObservableCollection<T> where T : BaseSong
{
...
}
public class Playlist
{
CollectionSong _collectionSong;
public CollectionSong<BaseSong> Collection
{
get { return _collectionSong; }
set {...}
}
public Playlist()
{}
...
}
我可以这样
Playlist plist= new Playlist();
plist.Collection = new CollectionSong<BaseSong>();
plist.Collection.Add(new ExtendedSong(){...});
ListView lv = new ListView();
lv.ItemSource = plist.Collection;
但是,我怎么能说ListView关于将listViewItem显示为ExtendedSong而不显示BaseSong?
p.S.集合只有BaseSong项目或只有ExtendedSong
private ListView CreateListView(PlaylistViewModel model)
{
System.Windows.Controls.ListView lv = new System.Windows.Controls.ListView();
lv.SetBinding(ListView.ItemsSourceProperty, new Binding("Collection")
{
Source = model,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
});
lv.SetBinding(ListView.ViewProperty, new Binding("ColumnConfig")
{
Converter = new VkPlayer.Helpers.ConfigToDynamicGridViewConverter()
});
return lv;
}
DataTemplate songLayout = new DataTemplate();
songLayout.DataType = typeof(ExtendedSong);
FrameworkElementFactory spFactory = new FrameworkElementFactory(typeof(TextBlock));
spFactory.Name = "textBoxFactory";
spFactory.SetBinding(TextBlock.TextProperty, new Binding("Bitrate"));
songLayout.VisualTree = spFactory;
ColumnConfig = new ColumnConfig { Columns = new List<Column> {
new Column { Header = "Title", DataField = "FullName" },
new Column { Header = "Bitrate", Template = songLayout}
}
};
public class ConfigToDynamicGridViewConverter : System.Windows.Data.IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var config = value as ColumnConfig;
if (config != null)
{
var grdiView = new GridView();
foreach (var column in config.Columns)
{
var grwCol = new GridViewColumn { Header = column.Header };
if (column.DataField != null)
{
var binding = new System.Windows.Data.Binding(column.DataField);
if (column.Converter != null)
binding.Converter = column.Converter as System.Windows.Data.IValueConverter;
if (column.ConverterParameter != null)
{
binding.ConverterParameter = column.ConverterParameter;
}
grwCol.DisplayMemberBinding = binding;
}
else
{
grwCol.CellTemplate = column.Template;
}
grdiView.Columns.Add(grwCol);
}
return grdiView;
}
return System.Windows.Data.Binding.DoNothing;
}
不工作,输出:System.Windows.Data错误:40:BindingExpression路径错误:在"object"BaseSong"(HashCode=23764897)""上找不到"Bitrate"属性
在WPF中,我们使用DataTemplate
s来定义数据对象在UI中的外观。有关数据绑定的详细信息,请参阅MSDN上的"数据绑定概述"页。因此,我们可以简单地为每个数据类型声明一个DataTemplate
,并且每个DataTemplate
的内容都可以访问该类型的属性。试试这样的东西:
<DataTemplate DataType="{x:Type YourPrefix:BaseSong}">
<TextBlock Text="{Binding Title}" />
</DataTemplate>
<DataTemplate DataType="{x:Type YourPrefix:ExtendedSong}">
<TextBlock Text="{Binding Bitrate}" />
</DataTemplate>
<ListBox ItemsSource="{Binding CollectionSong" ... />
这就是你所要做的。
public class CollectionSong<T> : ObservableCollection<T> where T : BaseSong
{
public CollectionSong<ExtendedSong> ToExSongs() {...}
}
public CollectionSong<BaseSong> CollectionEx
{
get { return Collection.ToExSongs(); }
set {...}
}