C# 绑定协方差集合
我有:C# 绑定协方差集合,c#,wpf,listview,binding,covariance,C#,Wpf,Listview,Binding,Covariance,我有: public class BaseSong { public string Artist { get; set; } public string Title { get; set; } public class ExtendedSong : BaseSong { public string Bitrate { get; set;} ... } public class Colle
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()
{}
...
}
公共类基本歌曲
{
公共弦乐艺术家
{
获得;设置;
}
公共字符串标题
{
获得;设置;
}
公共类扩展歌曲:BaseSong
{
公共字符串比特率{get;set;}
...
}
公共类集合Song:ObservableCollection其中T:BaseSong
{
...
}
公共类播放列表
{
收藏歌曲(u CollectionSong);;
公共收藏歌曲集
{
获取{return\u collectionSong;}
集合{…}
}
公共播放列表()
{}
...
}
我可以
Playlist plist= new Playlist();
plist.Collection = new CollectionSong<BaseSong>();
plist.Collection.Add(new ExtendedSong(){...});
ListView lv = new ListView();
lv.ItemSource = plist.Collection;
Playlist plist=新建播放列表();
plist.Collection=newcollectionsong();
plist.Collection.Add(新的ExtendedSong(){…});
ListView lv=新建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;
}
private ListView CreateListView(播放视图模型)
{
System.Windows.Controls.ListView lv=新的System.Windows.Controls.ListView();
lv.SetBinding(ListView.ItemsSourceProperty,新绑定(“集合”)
{
来源=模型,
UpdateSourceTrigger=UpdateSourceTrigger.PropertyChanged
});
lv.SetBinding(ListView.ViewProperty,新绑定(“ColumnConfig”)
{
Converter=new VkPlayer.Helpers.ConfigToDynamicGridViewConverter()
});
返回lv;
}
DataTemplate songLayout=新DataTemplate();
songLayout.DataType=typeof(ExtendedSong);
FrameworkElementFactory spFactory=新的FrameworkElementFactory(typeof(TextBlock));
spFactory.Name=“textBoxFactory”;
SetBinding(TextBlock.TextProperty,新绑定(“比特率”);
songLayout.VisualTree=spFactory;
ColumnConfig=新ColumnConfig{Columns=新列表{
新列{Header=“Title”,DataField=“FullName”},
新列{Header=“Bitrate”,Template=songLayout}
}
};
公共类ConfigToDynamicGridViewConverter:System.Windows.Data.IValueConverter
{
公共对象转换(对象值、类型targetType、对象参数、System.Globalization.CultureInfo区域性)
{
var config=列配置的值;
如果(配置!=null)
{
var grdiView=new GridView();
foreach(config.Columns中的var列)
{
var grwCol=newGridViewColumn{Header=column.Header};
if(column.DataField!=null)
{
var binding=new System.Windows.Data.binding(column.DataField);
if(column.Converter!=null)
binding.Converter=列.Converter作为System.Windows.Data.IValueConverter;
if(column.ConverterParameter!=null)
{
binding.ConverterParameter=column.ConverterParameter;
}
grwCol.DisplayMemberBinding=绑定;
}
其他的
{
grwCol.CellTemplate=column.Template;
}
grdiView.Columns.Add(grwCol);
}
返回grdiView;
}
返回System.Windows.Data.Binding.DoNothing;
}
不工作,输出:
System.Windows.Data错误:40:BindingExpression路径错误:在“对象”“BaseSong”(HashCode=23764897)上找不到“比特率”属性“在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>
这就是您所要做的。在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>
public class CollectionSong<T> : ObservableCollection<T> where T : BaseSong
{
public CollectionSong<ExtendedSong> ToExSongs() {...}
}
public CollectionSong<BaseSong> CollectionEx
{
get { return Collection.ToExSongs(); }
set {...}
}
这就是您所要做的。在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>
public class CollectionSong<T> : ObservableCollection<T> where T : BaseSong
{
public CollectionSong<ExtendedSong> ToExSongs() {...}
}
public CollectionSong<BaseSong> CollectionEx
{
get { return Collection.ToExSongs(); }
set {...}
}
这就是您所要做的。在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>
public class CollectionSong<T> : ObservableCollection<T> where T : BaseSong
{
public CollectionSong<ExtendedSong> ToExSongs() {...}
}
public CollectionSong<BaseSong> CollectionEx
{
get { return Collection.ToExSongs(); }
set {...}
}
这就是你所要做的。公共类集合歌曲:ObservableCollection其中T:BaseSong
public class CollectionSong<T> : ObservableCollection<T> where T : BaseSong
{
public CollectionSong<ExtendedSong> ToExSongs() {...}
}
public CollectionSong<BaseSong> CollectionEx
{
get { return Collection.ToExSongs(); }
set {...}
}
{
公共集合歌曲ToExSongs(){…}
}
公共收藏歌曲收藏X
{
获取{return Collection.ToExSongs();}
集合{…}
}
公共类收藏歌曲:ObservableEco