UWP 社区工具包 DataGrid 不显示数据

Posted

技术标签:

【中文标题】UWP 社区工具包 DataGrid 不显示数据【英文标题】:UWP Community Toolkit DataGrid not displaying data 【发布时间】:2019-11-09 18:52:38 【问题描述】:

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

在这一点上,我对自己做错了什么感到不知所措。我知道我的代码中有一些错误(显然或者它会起作用),但我似乎无法追踪它。有人可以看看下面的代码,看看他们是否能发现任何错误?

注意:我知道数据被正确读取,因为 a) 标题显示出来了,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>

【问题讨论】:

请尝试删除此行this.spellsList.DataContext = this.SpellBook; 而且你不需要为页面创建依赖属性,我检查了tk:DataGridTextColumn的绑定属性不正确。 你需要来自Spell类的绑定属性。 【参考方案1】:

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

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>

模型类

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;           

【讨论】:

在改造我必须反映您的更改的内容后,它可以工作了!据我所知,主要区别在于将其更改为在数据网格加载后加载数据,而不是在页面加载时加载,对吧? 好吧,这似乎违反直觉,但它确实有效。 :) 似乎它正在加载没有数据的数据网格,然后返回并再次加载它,这次是数据。

以上是关于UWP 社区工具包 DataGrid 不显示数据的主要内容,如果未能解决你的问题,请参考以下文章

如何更新 UWP Microsoft Toolkit DataGrid 中的单元格值?

WPF 桌面应用程序,Windows 10 通知 Toast 2016(UWP 社区工具包)

UWP 社区工具包中的主从视图

不规则行为 - XAML / UWP 社区工具包缩放动画

uwp GridView selectedItem 弹出窗口

uwp GridView selectedItem 弹出窗口