UWP Community Toolkit DataGrid 不显示数据

UWP Community Toolkit DataGrid not displaying data

我正在尝试使用来自 ObservableCollection 的数据在 UWP(来自社区工具包包)中加载 DataGrid。显示了从中读取数据的 CSV 文件中的 headers,但由于某种原因显示了 none 的数据行。我已经通读并尝试了至少 5 或 6 个关于 SO 的问题,所以虽然我知道以前有人问过这个问题,但这些答案似乎没有用。

此时我对自己做错了什么感到茫然。我知道我的代码中有一些错误(很明显,否则它会起作用),但我似乎无法找到它。有人可以看看下面的代码,看看他们是否能发现任何错误吗?

注意:我知道数据正在被正确读取,因为 a) headers 正在显示,并且 b) 我已经遇到断点并查看了 SpellBook 中的数据,它包含 408 个项目.

提前感谢任何可以提供帮助的人!

C#

public sealed partial class SpellPageBase : Page
{
    public ObservableCollection<Spell> SpellBook { get; set; }
    public List<Spell> spellData { get; set; }

    public static readonly DependencyProperty ComponentsProperty =
        DependencyProperty.Register("Components", typeof(string), typeof(SpellPageBase), new PropertyMetadata("Components"));

    public static readonly DependencyProperty DescriptionProperty =
        DependencyProperty.Register("Description", typeof(string), typeof(SpellPageBase), new PropertyMetadata("Description"));

    public static readonly DependencyProperty HighChangesProperty =
        DependencyProperty.Register("HighChanges", typeof(string), typeof(SpellPageBase), new PropertyMetadata("HighLevelChanges"));

    public static readonly DependencyProperty HighDescriptionProperty =
        DependencyProperty.Register("HighDescription", typeof(string), typeof(SpellPageBase), new PropertyMetadata("HighLevelDescription"));

    public static readonly DependencyProperty SchoolLevelProperty =
        DependencyProperty.Register("SpellLevel", typeof(int), typeof(SpellPageBase), new PropertyMetadata(0));

    public static readonly DependencyProperty IsRitualProperty =
        DependencyProperty.Register("IsRitual", typeof(bool), typeof(SpellPageBase), new PropertyMetadata(false));

    public static readonly DependencyProperty SchoolProperty =
        DependencyProperty.Register("School", typeof(string), typeof(SpellPageBase), new PropertyMetadata("School"));

    public static readonly DependencyProperty SpellNameProperty =
        DependencyProperty.Register("SpellName", typeof(string), typeof(SpellPageBase), new PropertyMetadata("Name"));

    public string Components
    {
        get { return (string)GetValue(ComponentsProperty); }
        set { SetValue(ComponentsProperty, value); }
    }

    public string Description
    {
        get { return (string)GetValue(DescriptionProperty); }
        set { SetValue(DescriptionProperty, value); }
    }

    public string HighChanges
    {
        get { return (string)GetValue(HighChangesProperty); }
        set { SetValue(HighChangesProperty, value); }
    }

    public string HighDescription
    {
        get { return (string)GetValue(HighDescriptionProperty); }
        set { SetValue(HighDescriptionProperty, value); }
    }

    public bool IsRitual
    {
        get { return (bool)GetValue(IsRitualProperty); }
        set { SetValue(IsRitualProperty, value); }
    }

    public string School
    {
        get { return (string)GetValue(SchoolProperty); }
        set { SetValue(SchoolProperty, value); }
    }

    public int SchoolLevel
    {
        get { return (int)GetValue(SchoolLevelProperty); }
        set { SetValue(SchoolLevelProperty, value); }
    }

    public string SpellName
    {
        get { return (string)GetValue(SpellNameProperty); }
        set { SetValue(SpellNameProperty, value); }
    }




    public SpellPageBase()
    {
        SpellBook = new ObservableCollection<Spell>();
        this.InitializeComponent();
        DataContext = this;

        //Load();
        //ReadFile();
    }

    public void ReadFile()
    {
        using (CsvReader csv = new CsvReader(new StreamReader("Assets\Spells5thEdition.csv"), true))
        {
            int fieldCount = csv.FieldCount;
            string[] headers = csv.GetFieldHeaders();

            while(csv.ReadNextRecord())
            {
                string key = csv[0];
                string name = csv[1];
                bool isRitual = csv[2] == "1" ? true : false;
                string ritualName = csv[3];
                int level = int.Parse(csv[4]);
                Enum.TryParse(csv[5], out School school);
                //int school = new School(int.Parse(csv[5]));
                string schoolLevel = csv[6];
                string castingTime = csv[7];
                string range = csv[8];
                string duration = csv[9];
                string components = csv[10];
                string materials = csv[11];
                string description = csv[12];
                string higherLevelMods = csv[13];
                string higherLevelDescription = csv[14];
                string save = csv[15];
                string classes = csv[16];
                string sourceBook = csv[17];
                string page = csv[18];
                string bookPage = csv[19];

                spellData.Add(new Spell(key, name, isRitual, ritualName, level, school, schoolLevel, castingTime, range, duration, components, materials, description, higherLevelMods, higherLevelDescription, save, classes, sourceBook, page, bookPage));
            }
        }
        ObservableCollection<Spell> spellBook = new ObservableCollection<Spell>(spellData);
    }

    private void Page_Loaded(object sender, RoutedEventArgs e)
    {
        this.spellData = new List<Spell>();
        ReadFile();

        //foreach(Spell s in spellData)
        //{
        //    SpellBook.Add(s);
        //}
        this.spellsList.DataContext = this.SpellBook;
        spellsList.ItemsSource = SpellBook;
        spellsList.UpdateLayout();
    }

}

XAML

<Page
x:Class="DungeoneerKit.SpellPageBase"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:DungeoneerKit"
xmlns:tk="using:Microsoft.Toolkit.Uwp.UI.Controls"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Loaded="Page_Loaded"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
    <Grid.Resources>
        <DataTemplate x:Key="RowDetailsTemplate">
            <StackPanel>
                <TextBlock Text="Spell Details:" Margin="10" />
                <Grid Margin="20, 10" Padding="5">
                    <Grid.RowDefinitions>
                        <RowDefinition />
                        <RowDefinition />
                        <RowDefinition />
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition />
                        <ColumnDefinition />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <TextBlock Grid.Row="0" Grid.Column="0" Text="Description: " FontWeight="SemiBold" FontSize="13" />
                    <TextBlock Grid.Row="1" Grid.Column="0" Text="At High-Levels: " FontWeight="SemiBold" FontSize="13" />
                    <TextBlock Grid.Row="2" Grid.Column="0" Text="High-Level Description: " FontWeight="SemiBold" FontSize="13" />
                    <TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Description}" FontSize="13" />
                    <TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding HighDescription}" FontSize="13" />
                    <TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding HighChanges}" FontSize="13" />
                </Grid>
            </StackPanel>
        </DataTemplate>
    </Grid.Resources>
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto" />
        <RowDefinition Height="Auto" />
    </Grid.RowDefinitions>
    <tk:DataGrid x:Name="spellsList"
                 Height="900"
                 Foreground="White"
                 DataContext="{Binding SpellBook}"
                 ItemsSource="{Binding SpellBook}"
                 Grid.Row="1"
                 Margin="12"
                 VerticalAlignment="Stretch"
                 HorizontalAlignment="Stretch"
                 HorizontalScrollBarVisibility="Visible"
                 VerticalScrollBarVisibility="Visible"
                 AlternatingRowBackground="Transparent"
                 AlternatingRowForeground="Gray"
                 AreRowDetailsFrozen="False"                     
                 AutoGenerateColumns="True"
                 CanUserSortColumns="True"
                 CanUserResizeColumns="True"
                 CanUserReorderColumns="True"
                 ColumnHeaderHeight="32"
                 MaxColumnWidth="400"
                 IsReadOnly="False"
                 RowDetailsTemplate="{StaticResource RowDetailsTemplate}"
                 RowDetailsVisibilityMode="VisibleWhenSelected"
                 SelectionMode="Extended">
        <!--<tk:DataGrid.Columns>
            <tk:DataGridTextColumn Header="Spell Name" Binding="{Binding SpellName}" />
            <tk:DataGridCheckBoxColumn Header="Ritual" Binding="{Binding IsRitual}" />
            <tk:DataGridTextColumn Header="Level-School" Binding="{Binding SchoolLevel}" />
            <tk:DataGridTextColumn Header="Components" Binding="{Binding Components}" />
        </tk:DataGrid.Columns>-->
    </tk:DataGrid>
</Grid>

根据您的要求,我简化了绑定步骤。请检查以下代码。

Xaml代码

<controls:DataGrid
    x:Name="MyDataGrid"
    HorizontalAlignment="Stretch"
    VerticalAlignment="Stretch"
    AlternatingRowBackground="Transparent"
    AlternatingRowForeground="Gray"
    AreRowDetailsFrozen="False"
    AreRowGroupHeadersFrozen="True"
    AutoGenerateColumns="False"
    CanUserReorderColumns="True"
    CanUserResizeColumns="True"
    CanUserSortColumns="False"
    ColumnHeaderHeight="32"
    FrozenColumnCount="0"
    GridLinesVisibility="None"
    HeadersVisibility="Column"
    HorizontalScrollBarVisibility="Visible"
    IsReadOnly="False"
    Loaded="DataGrid_Loaded"
    MaxColumnWidth="400"
    RowDetailsVisibilityMode="Collapsed"
    RowGroupHeaderPropertyNameAlternative="Range"
    SelectionMode="Extended"
    VerticalScrollBarVisibility="Visible"
    >
    <controls:DataGrid.RowGroupHeaderStyles>
        <Style TargetType="controls:DataGridRowGroupHeader">
            <Setter Property="Background" Value="LightGray" />
        </Style>
    </controls:DataGrid.RowGroupHeaderStyles>

    <controls:DataGrid.Columns>
        <controls:DataGridTextColumn
            Binding="{Binding Id}"
            Header="Id"
            Tag="Id"
            />
        <controls:DataGridTextColumn
            Binding="{Binding Title}"
            Header="Title"
            Tag="Title"
            />
        <controls:DataGridComboBoxColumn
            Binding="{Binding Link}"
            Header="Link"
            Tag="Link"
            />
        <controls:DataGridTextColumn
            Binding="{Binding Type}"
            Header="Type"
            Tag="Type"
            />
        <controls:DataGridTextColumn
            Binding="{Binding Remark}"
            Header="Remark"
            Tag="Remark"
            />
        <controls:DataGridTextColumn
            Binding="{Binding Time}"
            Header="Time"
            Tag="Time"
            />
    </controls:DataGrid.Columns>
</controls:DataGrid>

型号class

public class Item
{
    public string Id { get; set; }
    public string Title { get; set; }
    public string Link { get; set; }
    public string Type { get; set; }
    public string Remark { get; set; }
    public string Time { get; set; }
}

数据处理

private ObservableCollection<Item> Items;
private void DataGrid_Loaded(object sender, RoutedEventArgs e)
{
    using (var reader = new StreamReader("Assets\Archive.csv",true))
    using (var csv = new CsvReader(reader))
    {
        var records = csv.GetRecords<Item>();
        Items = new ObservableCollection<Item>(records);           
    }

    MyDataGrid.ItemsSource = Items;           
}