繁体   English   中英

绑定协方差集合WPF

[英]Binding covariance collection WPF

我有:

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;

但是,如何说关于将listViewItem显示为ExtendedSong而不是BaseSong的ListView?

PS集合仅包含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路径错误:在“对象”“ BaseSong”(HashCode = 23764897)上找不到“ Bitrate”属性

在WPF中,我们使用DataTemplate来定义数据对象在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 {...}
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM