简体   繁体   English

使用DataGridView显示DataTable的内容

[英]Using a DataGridView to display the contents of a DataTable

I have a three-column DataTable that contains data that I need to use in various ways. 我有一个三列DataTable,其中包含我需要以各种方式使用的数据。 The data in this DataTable comes from an Exchange Web Services call. 此DataTable中的数据来自Exchange Web服务调用。 The first column contains a row counter, the second contains the calendar name, and the third contains the calendar ID (which is a gibberish-looking string). 第一列包含行计数器,第二列包含日历名称,第三列包含日历ID(这是一个看起来像胡言乱语的字符串)。

Displaying the raw data in a DataGridView is straightforward. 在DataGridView中显示原始数据非常简单。 But I want the DataGridView's second column to be different: instead of showing the calendar ID, I want to show some text ("Copy"), which, when clicked, will copy the calendar ID to the user's clipboard. 但是我想要DataGridView的第二列是不同的:我想显示一些文本(“复制”),而不是显示日历ID,当单击时,它会将日历ID复制到用户的剪贴板。 Ideally it'd be styled like a hyperlink so the user knows it's not just some text in a box. 理想情况下,它的样式就像一个超链接,因此用户知道它不仅仅是一个盒子里的文本。 This can conceivably be done with a DataGridViewLinkColumn type with an event handler. 可以想象,这可以通过带有事件处理程序的DataGridViewLinkColumn类型来完成。

The piece I'm having trouble with is populating the rows. 我遇到麻烦的部分是填充行。

The following code sets up the columns just fine. 以下代码设置列很好。 But it doesn't populate the rows. 但它没有填充行。

private static DataGridView CreateCalendarGridView(DataTable calendarTable)
{
    //Bind to the data source
    var calendarGridView = new DataGridView();
    //calendarGridView.AutoGenerateColumns = false;
    calendarGridView.AutoSize = false;
    calendarGridView.DataSource = calendarTable;
    calendarGridView.ColumnHeadersVisible = true;

    //Create counter column
    var counterColumn = new DataGridViewTextBoxColumn();
    counterColumn.DataPropertyName = COUNTER_COLUMN_NAME;
    counterColumn.Name = COUNTER_COLUMN_NAME;
    counterColumn.HeaderText = COUNTER_COLUMN_LABEL;

    //Create the Calendar name column
    var calendarNameColumn = new DataGridViewTextBoxColumn();
    calendarNameColumn.DataPropertyName = CALENDAR_COLUMN_NAME;
    calendarNameColumn.Name = CALENDAR_COLUMN_NAME;
    calendarNameColumn.HeaderText = CALENDAR_COLUMN_LABEL;

    //Create the Copy ID hyperlink column
    var copyIdLinkColumn = new DataGridViewLinkColumn();
    copyIdLinkColumn.DataPropertyName = ID_COLUMN_NAME;
    copyIdLinkColumn.Name = ID_COLUMN_NAME;
    copyIdLinkColumn.HeaderText = ID_COLUMN_NAME;
    copyIdLinkColumn.UseColumnTextForLinkValue = false;
    copyIdLinkColumn.TrackVisitedState = true;
    copyIdLinkColumn.LinkColor = Color.Blue;
    copyIdLinkColumn.VisitedLinkColor = Color.Purple;
    copyIdLinkColumn.LinkBehavior = LinkBehavior.HoverUnderline;
    copyIdLinkColumn.Text = "Copy";
    copyIdLinkColumn.UseColumnTextForLinkValue = true;

    calendarGridView.Columns.Add(counterColumn);
    calendarGridView.Columns.Add(calendarNameColumn);
    calendarGridView.Columns.Add(copyIdLinkColumn);



    //I feel like I'm missing a foreach row in the DataTable which would
    //create the row of cells, but I'm not sure, because isn't that the
    //point of the calendarGridView.DataSource assignment above?



    return calendarGridView;
}

I feel like if I could get the rows to fill, I could figure out how to change the behavior of the clickable third column. 我觉得如果我可以填充行,我可以弄清楚如何更改可点击的第三列的行为。

What am I doing wrong? 我究竟做错了什么?

I've made a working sample. 我做了一个工作样本。 Please choose as the answer if it helps you. 如果有帮助,请选择答案。

.

public partial class CalendarTable_Stage1 : Form
{
    public CalendarTable_Stage1()
    {
        InitializeComponent();

        this.Controls.Add(makeDGV(DT));
    }

    DataTable DT
    {
        get
        {
            //Sample DataTable
            DataTable dtb = new DataTable();
            dtb.Columns.Add("empName");
            dtb.Columns.Add("empAddress");
            dtb.Rows.Add("Salim", "S.10, Santhi Nagar, Palakkad");
            dtb.Rows.Add("Manaf", "Thriveni, English church road, Palakkad");
            dtb.Rows.Add("Mohsin Khan", "Civil Nagar, Palakkad");

            return dtb;
        }
    }

    private void button1_Click(object sender, EventArgs e)
    {

    }

    DataGridView makeDGV(DataTable dt)
    {
        DataGridView dgv = new DataGridView();
        // set dgv properties

        dgv.Size = new Size(300, 400);
        dgv.Columns.Add("empName", "Name");

        DataGridViewLinkColumn linkCol = new DataGridViewLinkColumn();
        linkCol.HeaderText = "Address";
        linkCol.Name = "empAddress";
        dgv.Columns.Add(linkCol);
        dgv.AllowUserToAddRows = false; // This will greatly increase adding speed

        dgv.CellContentClick += new DataGridViewCellEventHandler(dgv_CellContentClick);

        foreach (DataRow row in dt.Rows)
        {
            DataGridViewLinkCell_Mine linker = new DataGridViewLinkCell_Mine();
            linker.Value = "Copy";
            linker.data = row[1].ToString();

            DataGridViewTextBoxCell cell = new DataGridViewTextBoxCell();
            cell.Value = row[0].ToString();
            dgv.Rows.Add();

            if (!dgv.AllowUserToAddRows)
            {
                dgv[0, dgv.Rows.Count - 1] = cell;
                dgv[1, dgv.Rows.Count - 1] = linker;
            }
            else
            {
                dgv[0, dgv.Rows.Count - 2] = cell;
                dgv[1, dgv.Rows.Count - 2] = linker;
            }

        }

        return dgv;
    }

    class DataGridViewLinkCell_Mine : DataGridViewLinkCell
    {
        public string data = "";
    }

    void dgv_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
        if (e.ColumnIndex == 1)
        {
            DataGridView dgv = (DataGridView)sender;
            DataGridViewLinkCell_Mine cell = (DataGridViewLinkCell_Mine)dgv[e.ColumnIndex, e.RowIndex];
            Clipboard.SetText(cell.data);


            MessageBox.Show(Clipboard.GetText());
        }
    }


}

This may answer part of your question. 这可能会回答您的部分问题。 If you will be using the datatable to update the database automatically, you may want to leave the datatable as is and not add columns to it. 如果您将使用数据表自动更新数据库,您可能希望保留数据表,而不是向其添加列。 In this case, you add your hyperlink column to the datagridview and not to the bound table. 在这种情况下,您将超链接列添加到datagridview而不是绑定表。 You don't need a foreach. 你不需要foreach。 Here is an example: 这是一个例子:

    //populate the data table dt
    //...

    //bind
    calendarGridView.DataSource = dt;

    //add a new link column (with some properties...) to the gridview
    DataGridViewLinkColumn copyIDLinkColumn = new DataGridViewLinkColumn();

    copyIDLinkColumn.UseColumnTextForLinkValue = true;
    copyIDLinkColumn.HeaderText = "Copy";
    copyIDLinkColumn.ActiveLinkColor = Color.White;
    copyIDLinkColumn.LinkBehavior = LinkBehavior.SystemDefault;
    copyIDLinkColumn.LinkColor = Color.Blue;
    copyIDLinkColumn.TrackVisitedState = true;
    copyIDLinkColumn.VisitedLinkColor = Color.Red;

    calendarGridView.Columns.Add(copyIDLinkColumn);
    copyIDLinkColumn.Text = "Click Me"; //Set it once as a default for all cells in col.

    //...

    // Event to handle column click (needs to be wired from designer for example)
    private void dataGridView_CellContentClick(object sender, DataGridViewCellEventArgs e)
    {
    //copy some data to clipboard...
    System.Windows.Forms.Clipboard.SetText(e.RowIndex.ToString());
    MessageBox.Show(e.RowIndex.ToString());

    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM