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