帮助将单元格内容自动填充到新窗口中

时间:2011-05-13 14:10:11

标签: c# datagrid

我要做的是,当用户双击数据网格中的单元格时,将打开一个新窗口,并将单元格内容自动填充到该窗口中,以便对其进行编辑。谁能帮我这个?感谢。

3 个答案:

答案 0 :(得分:0)

处理这种情况的一种天真的方法是直接在网格中的dbl-click事件中创建表单,并手动设置各个字段,显示它,获取新值并更新网格。

虽然这样可行但是直接在表单事件处理程序中做太多可能是个坏主意... 尝试将您的逻辑和域模型与表单分开。

然而,这可以给你一个起点...

var form = new CellEditingForm();
form.Field1.Text = cellValue;
form.ShowDialog();
string newValue = form.Field1.Text;
// update the grid here...

答案 1 :(得分:0)

这看起来像PropertyGrid可以很好地处理的事情。

这可能有助于您入门:Getting the Most Out of the .NET Framework PropertyGrid Control

答案 2 :(得分:0)

以下是如何在仅给定DataRow的情况下创建可编辑表单的非常粗略的演示。它使用Windows Forms,但无论您使用哪种框架,都可能拥有DataRow。如果你不这样做,你可以推断。

这展示了如何使用一堆控件动态创建表单。它确实提供了一种用于在用户搞砸之后回读数据的消除方法。

它没有做的是为您提供有关如何验证和保存用户已更改的数据的任何指导。我将给你一个提示:将DataRow附加到表单,使用TextBoxes上的绑定,并使用内置的ErrorProvider功能。这样行变得脏了,你用来读/写的任何机制(即TableAdapter)都会优雅地处理它。

我没有做到这一切,因为它取决于你使用的框架。这只是一个简单的例子,可以帮助您入门。如果您对此处的具体问题有疑问,请提出新的具体问题。

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

class DemoForm : Form
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        Application.Run(new DemoForm());
    }

    public DemoForm()
    {
        DataTable dataTable = new DataTable { Columns = { "First", "Second", "Third" } };
        dataTable.Rows.Add("This", "Is", "Data");
        dataTable.Rows.Add("Some", "More", "Values");
        DataGridView dgv = new DataGridView
        {
            Dock = DockStyle.Fill,
            DataSource = dataTable,
            RowHeadersVisible = false,
            SelectionMode = DataGridViewSelectionMode.FullRowSelect,
            ReadOnly = true,
        };
        dgv.DoubleClick += (s, e) =>
            {
                if (dgv.SelectedRows.Count > 0)
                {
                    DataRow dataRow = (dgv.SelectedRows[0].DataBoundItem as DataRowView).Row;
                    using (GenericDataRowForm form = new GenericDataRowForm(dataRow))
                    {
                        if (form.ShowDialog(this) == DialogResult.OK)
                        {
                            // TODO: Validate and save data

                            // Just showing how to iterate GenericDataRowForm.Items
                            foreach (KeyValuePair<string, string> pair in form.Items)
                                Trace.WriteLine(String.Format("Column = {0}, Value = {1}", pair.Key, pair.Value));
                        }
                    }
                }
            };
        Controls.Add(dgv);
    }
}

class GenericDataRowForm : Form
{
    public GenericDataRowForm()
    {
    }
    public GenericDataRowForm(DataRow row)
    {
        // Basic dialog box styles
        FormBorderStyle = FormBorderStyle.FixedDialog;
        MinimizeBox = MaximizeBox = ShowInTaskbar = false;
        StartPosition = FormStartPosition.CenterParent;

        // You would probably want to set the caption (this.Text) to
        //  something meaningful from the outside, so left it out here.

        // Record the number of items
        itemCount = row.Table.Columns.Count;

        // Create a TableLayoutPanel to arrange the Label/TextBox pairs (and the Ok/Cancel buttons).
        TableLayoutPanel panel = new TableLayoutPanel
        {
            Name = "LayoutPanel",
            ColumnCount = 2,
            ColumnStyles = { new ColumnStyle(), new ColumnStyle(SizeType.Percent, 100F) },
            RowCount = itemCount + 1,
            // We will dock it later, but we want to know how big it should be.
            AutoSize = true,
        };

        int itemIndex = 0; // Intentionally declared outside as we'll use it for the buttons below.
        for (; itemIndex < itemCount; itemIndex++)
        {
            panel.RowStyles.Add(new RowStyle());
            string columnName = row.Table.Columns[itemIndex].ColumnName;
            panel.Controls.Add(new Label { Text = columnName, AutoSize = true, Anchor = AnchorStyles.Right }, 0, itemIndex);
            // Note that the text box has its Name set to the data column name and it's Text to the value of that column.
            panel.Controls.Add(new TextBox { Name = columnName, Text = row[itemIndex].ToString(), Dock = DockStyle.Fill }, 1, itemIndex);
        }

        // Add Ok and Cancel buttons
        panel.RowStyles.Add(new RowStyle());
        panel.Controls.Add(new Button { Text = "Ok", Name = "OkButton", DialogResult = DialogResult.OK }, 0, itemIndex);
        panel.Controls.Add(new Button { Text = "Cancel", Name = "CancelButton", DialogResult = DialogResult.Cancel }, 1, itemIndex);
        AcceptButton = panel.Controls["OkButton"] as IButtonControl;
        CancelButton = panel.Controls["CancelButton"] as IButtonControl;

        // Adjust this Form's size to the panel.
        ClientSize = new Size(320, panel.Height + 10);
        // Then dock the panel so that it conforms to the Form.
        panel.Dock = DockStyle.Fill;

        Controls.Add(panel);
    }

    public int ItemCount
    {
        get { return itemCount; }
    }

    // We need some way for the outside world to view the data that
    //  might have been edited by the user. This could be much more
    //  complicated. As a simple example, this allows the consumer
    //  to iterate over each item as a KeyValuePair. The key is the
    //  data column name and the value is the Text field of the TextBox.
    public IEnumerable<KeyValuePair<string, string>> Items
    {
        get
        {
            if (itemCount > 0)
            {
                TableLayoutPanel panel = Controls["LayoutPanel"] as TableLayoutPanel;
                foreach (Control control in panel.Controls)
                {
                    TextBox textBox = control as TextBox;
                    if (textBox != null)
                        yield return new KeyValuePair<string, string>(textBox.Name, textBox.Text);
                }
            }
        }
    }

    private int itemCount = 0;
}