wpf中的文本块列表

本文关键字:列表 文本 wpf | 更新日期: 2023-09-27 18:06:54

我有书籍集合和listview用于表示书籍数据。我试着做一个文本块列表。每个文本块需要转换数据与转换器采取一个模型,并给出一个字符串的数据,但我不知道如何绑定集合和传递一个模型的转换器。

书模型:

namespace Books.Models
{
    public class Book : IModel
    {
        public Book()
        {
            Authors = new List<Author>();
            Tags = new List<string>();
        }
        public string Name { get; set; }
        public List<Author> Authors { get; set; }
        public string ISBN { get; set; }
        public int Pages { get; set; }
        public List<string> Tags { get; set; }
        public int PublicationYear { get; set; }
        public House House { get; set; }
    }
}

书籍收藏:

namespace Books.Collections
{
    public class ModelsCollection : Dictionary<string, IModel>
    {
        public void Add(IModel model)
        {
            Add(model.Name, model);
        }
        public IEnumerable<IModel> GetAll()
        {
            foreach (IModel model in Values)
                yield return model;   
        }
    }
}

转换器:

namespace Books
{
    [ValueConversion(typeof(ModelsCollection), typeof(string))]
    public class BooksConvertor : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            Book book = (Book)value;
            return book.Name + " - " + string.Join(", ", book.Authors.Select(x => x.Name));
        }
        public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

ListView in XAML

    <ListView >
        <TextBlock Text="{Binding Path=Book,Converter={StaticResource BooksConvertor}}"/>
    </ListView>

wpf中的文本块列表

首先,您需要一种方法来设置您正在使用的窗口/视图的DataContext。我已经创建了一个简单的ViewModel来做到这一点(使用您的模型)。

public class ViewModel
{
    public List<IModel> Books { get; private set; }
    public ViewModel()
    {
        var modelCollection = new ModelsCollection();
        for (var i = 0; i < 10; i++)
        {
            var testBook = new Book
            {
                Name = "Test Book " + i
            };
            testBook.Authors.Add(new Author
            {
                Name = "Test Author " + i
            });
            modelCollection.Add(testBook);;
        }
        Books = modelCollection.GetAll();
    }
}

Window代码背后的Ctor中,只需执行:

DataContext = new ViewModel();

接下来,您的ListView需要绑定到ViewModel中指定的Books集合,并且还有一个预定义的模板来正确绑定到每个Book对象。您需要将ListView更新为:

<ListView ItemsSource="{Binding Books}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding ., Converter={StaticResource BooksConvertor}}"/>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

最后,您需要更新转换器以使用IModel类型,因为这是传入的数据。

[ValueConversion(typeof(IModel), typeof(string))]
public class BooksConvertor : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var book = value as Book;
        if (book != null)
        {
            return book.Name + " - " + string.Join(", ", book.Authors.Select(x => x.Name));
        }
        else
        {
            return "";
        }
    }
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}