首页 > 解决方案 > 在 C# WPF 中读取 CSV 文件

问题描述

我有一个我正在创建的应用程序,以便在 C# 中进行更多练习以及读取和写入 CSV 文件。我想将一些不同的动物从 CSV 文件显示到 WPF 中的数据网格中。我已经成功地在我的应用程序的一部分中使用完全相同的代码来显示来自不同 CSV 文件的动物类别,但是任何人都可以看到为什么这不会显示动物。我已将代码更改为不同的 CSV 位置,并添加到我想显示的不同列中,但我无法弄清楚为什么这不起作用。

下面是我的数据网格部分用于显示动物的代码。

private void DataGridViewAnimals_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            Animal animal= new Animal();
            string[] AnimalArray;

            DataTable dt = new DataTable();
            dt.Columns.Add("Animal", typeof(string));

            using (StreamReader reader = new StreamReader(@"C:\Users\ashle\OneDrive\Documents\Uni\Level 5\Object Orientated Programming\Practical\CSV Files\animal.csv"))
            {
                while (!reader.EndOfStream)
                {
                    AnimalArray = reader.ReadLine().Split(',');

                    animal.Type = AnimalArray[0];
                    animal.Category = AnimalArray[1];
                    animal.Colour = AnimalArray[2];
                    animal.Origin = AnimalArray[3];

                    dt.Rows.Add(AnimalArray);
                }
                DataView dv = new DataView(dt);
                DataGridViewAnimals.ItemsSource = dv;
            }
        }

抱歉,我对 C# 和 WPF 很陌生,所以任何人都可以看看是否有任何问题。我曾尝试寻找不同的方法来做到这一点,但我没有运气。如果您需要更多信息,请询问:) 谢谢

编辑:这是我的 DataGrid 代码,它从我的 CSV 文件中提取数据

private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            AnimalCategory animalCategory = new AnimalCategory();
            string[] CategoryArray;

            DataTable dt = new DataTable();
            dt.Columns.Add("Animal Category", typeof(string));

            using (StreamReader reader = new StreamReader(@"C:\Users\ashle\OneDrive\Documents\Uni\Level 5\Object Orientated Programming\Practical\CSV Files\animalcategory.csv"))
            {
                while (!reader.EndOfStream)
                {
                    CategoryArray = reader.ReadLine().Split(',');

                    animalCategory.Category = CategoryArray[0];

                    dt.Rows.Add(CategoryArray);
                }
                DataView dv = new DataView(dt);
                DataGridViewAnimalCategories.ItemsSource = dv;
            }
        }

下面显示了我的 XAML UI 的第一段代码不起作用的标记。

<Window x:Class="AnimalWatchersUnited2.Animals"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:AnimalWatchersUnited2"
        mc:Ignorable="d"
        Title="Animals" Height="450" Width="800" >
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="1.1*"/>
            <RowDefinition/>
            <RowDefinition/>
            <RowDefinition/>
        </Grid.RowDefinitions>

        <Rectangle Fill="LightPink" Grid.Row="0" Grid.ColumnSpan="6"/>
        <Label Content="Animal Watchers United" FontSize="36" HorizontalAlignment="Center" VerticalAlignment="Center" Grid.ColumnSpan="6" FontFamily="Candara" />
        <Button Click="ClickMainMenu" Content="Main Menu" Grid.Column="0" Grid.Row="1" Height="50px" Width="110px" Margin="10,0,12,50"/>
        <Button Click="ClickAnimalCategories" Content="Animal Categories" Grid.Column="1" Grid.Row="1" Height="50px" Width="110px" Margin="10,0,12,50"/>
        <Button Content="Animals" Grid.Column="2" Grid.Row="1" Height="50px" Width="110px" Margin="12,0,10,50"/>
        <Button Content="Sightings" Grid.Column="3" Grid.Row="1" Height="50px" Width="110px" Margin="12,0,10,50"/>
        <Button Content="Wishlist" Grid.Column="4" Grid.Row="1" Height="50px" Width="110px" Margin="12,0,10,50"/>
        <Button Click="ClickLogout" Content="Logout" Grid.Column="5" Grid.Row="1" Height="50px" Width="110px" Margin="10,0,10,50"/>


        <DataGrid Name="DataGridViewAnimals" Grid.Column="1" Grid.Row="2" RenderTransformOrigin="0.808,0.668" Grid.ColumnSpan="3" Grid.RowSpan="2" SelectionChanged="DataGridViewAnimals_SelectionChanged"/>
    </Grid>
</Window>

标签: c#wpfcsv

解决方案


问题是您要将字符串数组添加到只有一列的网格中。当您只有 1 列时,它没有空间为每只动物添加 4 个项目。如果我是正确的,您应该会得到一个内部异常,上面写着“输入数组比此表中的列数长”。

尝试为要输入的值定义更多列,如下所示:

string[] AnimalArray;

DataTable dt = new DataTable();
dt.Columns.Add("Type", typeof(string));
dt.Columns.Add("Category", typeof(string));
dt.Columns.Add("Colour", typeof(string));
dt.Columns.Add("Origin", typeof(string));

using (StreamReader reader = new StreamReader(@"C:\Users\ashle\OneDrive\Documents\Uni\Level 5\Object Orientated Programming\Practical\CSV Files\animal.csv"))
{
    while (!reader.EndOfStream)
    {
        AnimalArray = reader.ReadLine().Split(',');

        dt.Rows.Add(AnimalArray);
    }
    DataView dv = new DataView(dt);
    DataGridViewAnimals.ItemsSource = dv;
}

如果这仍然不起作用,请向我们展示与 UI 的 xaml 标记一起工作的代码。

编辑:正如 Fildor 所指出的,您没有以这种方式使用 animal 变量,因此设置其属性没有意义,除非您想在其他地方使用数据。

编辑 2:第二个问题在于事件本身。WORKS 的代码在方法 Window Loaded 中,我想在加载窗口时将调用该方法。这就是它起作用的原因。

另一方面,SelectionChanged 在选择网格中的项目时被调用。由于网格中还没有数据,因此首先不能选择任何项目来调用该方法。

换句话说,代码的位置不正确。只需从 UI 中的 DataGrid 中删除 SelectionChanged 事件处理程序,然后为其中一个按钮添加一个单击方法(我猜是 Animals 按钮),然后将代码放在那里。


推荐阅读