如何在不使用C#Winforms中的数据库的情况下在列表上使用DatagridView

如何在不使用C#Winforms中的数据库的情况下在列表上使用DatagridView,c#,winforms,datagridview,C#,Winforms,Datagridview,在我的项目中,我想从文件中读取数据,并将DataGridView更新为一个简单的列表。我希望这样可以在运行时更新列表,然后在保存时希望将列表的最终内容更新为文件 在谷歌搜索上看到的大多数解决方案中,我举了一些例子,说明如何使用DatagridView和用于更新DatagridView的数据库连接。用于插入、更新和删除操作。对于我的答案,有很多建议包括添加INotifyProperty和基于IBindingList的实现,这可能是一种过分的做法 我只想发布我的解决方案,其中涉及使用Datagrid

在我的项目中,我想从文件中读取数据,并将DataGridView更新为一个简单的列表。我希望这样可以在运行时更新列表,然后在保存时希望将列表的最终内容更新为文件

在谷歌搜索上看到的大多数解决方案中,我举了一些例子,说明如何使用DatagridView和用于更新DatagridView的数据库连接。用于插入、更新和删除操作。对于我的答案,有很多建议包括添加INotifyProperty和基于IBindingList的实现,这可能是一种过分的做法

我只想发布我的解决方案,其中涉及使用Datagridview更新列表。这里使用的代码片段是一个大型项目的一部分,在这个项目中,将数据从Datagridview更新到列表并返回是一个非常大的挑战,因为最初是使用数据库实现的,需要删除数据库的依赖关系


在发布这个问题时,我有了一个解决问题的方法。为了解决这个问题,我从前面的各种问题中收集了一些零碎的建议。我不是在评论中寻找建议。如果有人想向我展示解决此问题的更好方法,请发布一个带有工作代码的答案。

下面是一个示例,我使用DatagridView对列表(类对象列表
PersonState
)执行插入更新和删除

DatagridView的数据源需要包含一个DataTable,为了弥补这一差距,我使用了一个名为
ConvertToDatatable()
的函数

作为我的出发点,我从一个由阿努普·库马尔·夏尔马提出的项目开始

使用以下代码:

using System;
using System.Collections.Generic;
using System.Data;
using System.Windows.Forms;

namespace InsertUpdateDelete {
    public partial class Form1 : Form {
        public class PersonState {
            public string Name { get; set; }
            public string State { get; set; }
        }
        public List<PersonState> listOfPersonState;
        public Form1() {
            InitializeComponent();
            listOfPersonState = new List<PersonState>();
        }
        //Display Data in DataGridView  
        private void DisplayData() {
            DataTable dt = new DataTable();
            dt = ConvertToDatatable();
            dataGridView1.DataSource = dt;
        }
        //Clear Data  
        private void ClearData() {
            txt_Name.Text = "";
            txt_State.Text = "";
        }
        public DataTable ConvertToDatatable() {
            DataTable dt = new DataTable();
            dt.Columns.Add("Name");
            dt.Columns.Add("State");
            foreach (var item in listOfPersonState) {
                var row = dt.NewRow();
                row["Name"] = item.Name;
                row["State"] = item.State;
                dt.Rows.Add(row);
            }
            return dt;
        }
        private void AddToList(string text1, string text2) {
            listOfPersonState.Add(new PersonState { Name = text1, State = text2 });
        }
        private void UpdateToList(string text1, string text2) {
            int index = dataGridView1.SelectedRows[0].Index;
            listOfPersonState[index] = new PersonState { Name = text1, State = text2 };
        }
        private void DeleteToList() {
            int index = dataGridView1.SelectedRows[0].Index;
            listOfPersonState.RemoveAt(index);
        }
        private void btn_Insert_Click(object sender, EventArgs e) {
            if (txt_Name.Text != "" && txt_State.Text != "") {
                AddToList(txt_Name.Text, txt_State.Text);
                //MessageBox.Show("Record Inserted Successfully");
                DisplayData();
                ClearData();
            } else {
                MessageBox.Show("Please Provide Details!");
            }
        }
        private void btn_Update_Click(object sender, EventArgs e) {
            if (txt_Name.Text != "" && txt_State.Text != "") {
                if (dataGridView1.SelectedRows != null && dataGridView1.SelectedRows.Count > 0) {
                    UpdateToList(txt_Name.Text, txt_State.Text);
                    //MessageBox.Show("Record Updated Successfully");
                    DisplayData();
                    ClearData();
                }    
            } else {
                MessageBox.Show("Please Select Record to Update");
            }
        }
        private void btn_Delete_Click(object sender, EventArgs e) {
            if (dataGridView1.SelectedRows != null && dataGridView1.SelectedRows.Count > 0) {
                DeleteToList();
                //MessageBox.Show("Record Deleted Successfully!");
                DisplayData();
                ClearData();
            } else {
                MessageBox.Show("Please Select Record to Delete");
            }
        }

        private void dataGridView1_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
            FillInputControls(e.RowIndex);
        }
        private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
            FillInputControls(e.RowIndex);
        }
        private void FillInputControls(int Index) {
            if (Index > -1) {
                txt_Name.Text = dataGridView1.Rows[Index].Cells[0].Value.ToString();
                txt_State.Text = dataGridView1.Rows[Index].Cells[1].Value.ToString();
            }
        }
    }
}
我使用了:

public class PersonState {
    public string Name { get; set; }
    public string State { get; set; }
}
出于某种原因,在试图分配价值观时,前者不起作用

  • 我已将对象列表设置为类变量,以便所有 函数可以直接访问该列表,而不是传递该列表 作为一个参数

    个人状态的公共列表

  • 我将插入、更新和删除的逻辑替换为DB,插入 更新并删除到列表

    private void AddToList(string text1, string text2) {
        listOfPersonState.Add(new PersonState { Name = text1, State = text2 });
    }
    private void UpdateToList(string text1, string text2) {
        int index = dataGridView1.SelectedRows[0].Index;
        listOfPersonState[index] = new PersonState { Name = text1, State = text2 };
    }
    private void DeleteToList() {
        int index = dataGridView1.SelectedRows[0].Index;
        listOfPersonState.RemoveAt(index);
    }
    
  • 注意:我直接从列表中分配网格,因此我的网格和列表始终具有相同的索引,因为我在插入、更新和删除按钮操作时使用显示功能来确保这一点

    private void DisplayData() {
        DataTable dt = new DataTable();
        dt = ConvertToDatatable();
        dataGridView1.DataSource = dt;
    }
    public DataTable ConvertToDatatable() {
        DataTable dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("State");
        foreach (var item in listOfPersonState) {
            var row = dt.NewRow();
            row["Name"] = item.Name;
            row["State"] = item.State;
            dt.Rows.Add(row);
        }
        return dt;
    }
    

    下面是一个示例,我使用DatagridView对列表(类对象列表
    PersonState
    )执行插入更新和删除操作

    DatagridView的数据源需要包含一个DataTable,为了弥补这一差距,我使用了一个名为
    ConvertToDatatable()
    的函数

    作为我的出发点,我从一个由阿努普·库马尔·夏尔马提出的项目开始

    使用以下代码:

    using System;
    using System.Collections.Generic;
    using System.Data;
    using System.Windows.Forms;
    
    namespace InsertUpdateDelete {
        public partial class Form1 : Form {
            public class PersonState {
                public string Name { get; set; }
                public string State { get; set; }
            }
            public List<PersonState> listOfPersonState;
            public Form1() {
                InitializeComponent();
                listOfPersonState = new List<PersonState>();
            }
            //Display Data in DataGridView  
            private void DisplayData() {
                DataTable dt = new DataTable();
                dt = ConvertToDatatable();
                dataGridView1.DataSource = dt;
            }
            //Clear Data  
            private void ClearData() {
                txt_Name.Text = "";
                txt_State.Text = "";
            }
            public DataTable ConvertToDatatable() {
                DataTable dt = new DataTable();
                dt.Columns.Add("Name");
                dt.Columns.Add("State");
                foreach (var item in listOfPersonState) {
                    var row = dt.NewRow();
                    row["Name"] = item.Name;
                    row["State"] = item.State;
                    dt.Rows.Add(row);
                }
                return dt;
            }
            private void AddToList(string text1, string text2) {
                listOfPersonState.Add(new PersonState { Name = text1, State = text2 });
            }
            private void UpdateToList(string text1, string text2) {
                int index = dataGridView1.SelectedRows[0].Index;
                listOfPersonState[index] = new PersonState { Name = text1, State = text2 };
            }
            private void DeleteToList() {
                int index = dataGridView1.SelectedRows[0].Index;
                listOfPersonState.RemoveAt(index);
            }
            private void btn_Insert_Click(object sender, EventArgs e) {
                if (txt_Name.Text != "" && txt_State.Text != "") {
                    AddToList(txt_Name.Text, txt_State.Text);
                    //MessageBox.Show("Record Inserted Successfully");
                    DisplayData();
                    ClearData();
                } else {
                    MessageBox.Show("Please Provide Details!");
                }
            }
            private void btn_Update_Click(object sender, EventArgs e) {
                if (txt_Name.Text != "" && txt_State.Text != "") {
                    if (dataGridView1.SelectedRows != null && dataGridView1.SelectedRows.Count > 0) {
                        UpdateToList(txt_Name.Text, txt_State.Text);
                        //MessageBox.Show("Record Updated Successfully");
                        DisplayData();
                        ClearData();
                    }    
                } else {
                    MessageBox.Show("Please Select Record to Update");
                }
            }
            private void btn_Delete_Click(object sender, EventArgs e) {
                if (dataGridView1.SelectedRows != null && dataGridView1.SelectedRows.Count > 0) {
                    DeleteToList();
                    //MessageBox.Show("Record Deleted Successfully!");
                    DisplayData();
                    ClearData();
                } else {
                    MessageBox.Show("Please Select Record to Delete");
                }
            }
    
            private void dataGridView1_RowHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) {
                FillInputControls(e.RowIndex);
            }
            private void dataGridView1_CellClick(object sender, DataGridViewCellEventArgs e) {
                FillInputControls(e.RowIndex);
            }
            private void FillInputControls(int Index) {
                if (Index > -1) {
                    txt_Name.Text = dataGridView1.Rows[Index].Cells[0].Value.ToString();
                    txt_State.Text = dataGridView1.Rows[Index].Cells[1].Value.ToString();
                }
            }
        }
    }
    
    我使用了:

    public class PersonState {
        public string Name { get; set; }
        public string State { get; set; }
    }
    
    出于某种原因,在试图分配价值观时,前者不起作用

  • 我已将对象列表设置为类变量,以便所有 函数可以直接访问该列表,而不是传递该列表 作为一个参数

    个人状态的公共列表

  • 我将插入、更新和删除的逻辑替换为DB,插入 更新并删除到列表

    private void AddToList(string text1, string text2) {
        listOfPersonState.Add(new PersonState { Name = text1, State = text2 });
    }
    private void UpdateToList(string text1, string text2) {
        int index = dataGridView1.SelectedRows[0].Index;
        listOfPersonState[index] = new PersonState { Name = text1, State = text2 };
    }
    private void DeleteToList() {
        int index = dataGridView1.SelectedRows[0].Index;
        listOfPersonState.RemoveAt(index);
    }
    
  • 注意:我直接从列表中分配网格,因此我的网格和列表始终具有相同的索引,因为我在插入、更新和删除按钮操作时使用显示功能来确保这一点

    private void DisplayData() {
        DataTable dt = new DataTable();
        dt = ConvertToDatatable();
        dataGridView1.DataSource = dt;
    }
    public DataTable ConvertToDatatable() {
        DataTable dt = new DataTable();
        dt.Columns.Add("Name");
        dt.Columns.Add("State");
        foreach (var item in listOfPersonState) {
            var row = dt.NewRow();
            row["Name"] = item.Name;
            row["State"] = item.State;
            dt.Rows.Add(row);
        }
        return dt;
    }
    

    因此,在读取之后,您有一个MyData对象序列。您希望在DataGridView中显示所有MyData对象(或子部分)

    操作员可以更改显示的值、添加一些新行或删除行。某些列可能是只读的,无法更改

    按下OK按钮后,您希望从DataGridView读取所有MyData对象并将其保存在文件中

    大多数工作都可以使用表单设计器完成

    • 在设计器中打开窗体类
    • 在此窗体上拖动DataGridView
    • 在此窗体上拖动BindingSource
    • 右键单击BindingSource并选择properties
    • 单击右侧箭头上DataSource中的属性窗口
    • 如果MyData在此处不可见,请选择“添加项目数据源”
    • 在新窗口中选择对象
    • 选择添加的数据源作为BindingSource的数据源
    • 在DataGridView的属性中,将bindingSource分配给数据源
    突然:您的DataGridView拥有MyData的公共属性列。神奇的是,这些列的类型是正确的。它们能够显示值。只读属性具有只读列,读写属性可编辑

    要显示数据,请执行以下操作:

    void FillDataGridView(IEnumerable<MyData> dataToDisplay)
    {
        this.bindingSource1.DataSource = new BindingList<MyData>(dataToDisplay.ToList();
    }
    
    void FillDataGridView(IEnumerable dataToDisplay)
    {
    this.bindingSource1.DataSource=新绑定列表(dataToDisplay.ToList();
    }
    
    编辑后读取所有数据的步骤

    IEnumerable<MyData> ReadDataGridView()
    {
        return this.bindingSource1.List.Cast<MyData>();
    }
    
    IEnumerable ReadDataGridView()
    {
    返回此.bindingSource1.List.Cast();
    }
    
    这使操作员能够添加和删除行以及编辑值。 如果不希望操作员执行此操作,请调整DataGridView属性
    如果列的显示值不符合您的喜好,请编辑列属性(不同的标题文本、不同的显示格式、不同的背景颜色等)

    这样,读取后,您就有了一系列MyData对象。您希望在DataGridView中显示所有MyData对象(或子部分)

    操作员可以更改显示的值、添加一些新行或删除行。某些列可能是只读的,无法更改

    按下OK按钮后,您希望从DataGridView读取所有MyData对象并将其保存在文件中

    大多数工作都可以使用表单设计器完成

    • 在设计器中打开窗体类
    • 在此窗体上拖动DataGridView
    • 在此窗体上拖动BindingSource