如何在XAML中的DataGrid中访问列表内对象的属性

时间:2018-10-02 10:49:24

标签: c# wpf xaml binding

我已经搜索了一段时间,但是我在想,也许我在寻找错误的方向。我有一个DataGrid,其中ItemsSource设置为Book对象的列表。同时,Book对象包含Chapter对象的列表。

public class Book {
    public string Title;
    public List<Chapter> AvailableChapters;
}

public class Chapter {
    public int ChapterNumber;
    public int NumberOfPages;
}

我在DataGrid中以这种方式使用它们:

<DataGrid SelectionMode="Extended"
              HeadersVisibility="Column"
              CanUserAddRows="False">
    <DataGrid.Columns>
            <DataGridTextColumn Header="Title" Binding="{Binding Title}" />
            <DataGridTextColumn Header="Available chapters" Binding="{Binding AvailableChapters}" />
            <!-- This is what I tried
            <DataGridTemplateColumn Header="Available chapters">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ListBox ItemsSource="{Binding AvailableChapters}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>-->
    </DataGrid.Columns>
</DataGrid>

我的目的是将书中的章节列表显示为字符串列表,其中每个字符串都是章节编号(ChapterNumber属性)。因此,我试图通过某种方式访问​​ChapterNumber属性中的ChapterList属性。试图甚至使用ListBoxAvailableChapters.ChapterNumber,但没有任何意义。

示例:

enter image description here

修改

尝试使用转换器,但尽管该值不为null,但表示其长度为零。

public class ChapterListToStringListConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            List<Chapter> chapters = value as List<Chapter>;
            if (chapters == null)
            {
                chapters = new List<Chapter>();
            }

            Debug.Print(chapters.Count.ToString());    // "0"
            Debug.Print(chapters[0].ChapterNumber);    // Error: index out of range
            string result = string.Join(" ", chapters.Select(chap => chap.Name));
            return result;
        }
    }
}

3 个答案:

答案 0 :(得分:1)

数据绑定的源必须是属性,而不是您当前拥有的字段。

要获取包含所有可用章节的单个字符串,只需将一个计算所得的属性添加到Book类中,该属性将合并列表中的所有章节项。

public class Book 
{
    public string Title {get; set;}
    public List<Chapter> AvailableChapters; {get;}

    public string AvailableChaptersDisplay
    { get {return string.Join( " ", AvailableChapters.Select( c => c.ChapterNumber )); } }
}

答案 1 :(得分:1)

如果在初始化视图之后添加章节,则AvailableChapters应该是一个ObservableCollection:

public class Book
{
    public string Title { get; set; }

    public ObservableCollection<Chapter> AvailableChapters { get; }
        = new ObservableCollection<Chapter>();
}

在您的转换器中,只需检查value是否为IEnumerable:

public object Convert(
    object value, Type targetType, object parameter, CultureInfo culture)
{
    var chapters = value as IEnumerable<Chapter>;

    return chapters == null
        ? "-"
        : string.Join(" ", chapters.Select(chap => chap.ChapterNumber));
}

答案 2 :(得分:0)

您可以添加一个属性来为您计算。

public class Book {
    public string Title;
    public List<Chapter> AvailableChapters;
    public string AvailableChaptersString
    {
        get {return list_concatenated_in_desired_format; }
    }

}