绑定协方差集合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中,我们使用DataTemplates来定义数据对象在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" ... />

这就是你所要做的。

绑定协方差集合WPF

public class CollectionSong<T> : ObservableCollection<T>  where T : BaseSong
{
   public CollectionSong<ExtendedSong> ToExSongs() {...}
}
public CollectionSong<BaseSong> CollectionEx
    { 
         get { return Collection.ToExSongs(); }
         set {...}
    }