Помощь с автоматическим заполнением содержимого ячеек в новом окне

#c# #datagrid

#c# #datagrid

Вопрос:

Что я хочу сделать, так это то, что когда пользователь дважды щелкает по ячейке в datagrid, открывается новое окно, и содержимое ячеек автоматически заполняется в это окно, чтобы их можно было редактировать. Кто-нибудь может мне помочь с этим? Спасибо.

Комментарии:

1. Пожалуйста, покажите какой-нибудь пример кода. SO не является сайтом по найму кода.

2. Я не прошу весь код целиком, просто кое-что, что поможет мне начать. учебные пособия и т.д….

3. Пожалуйста, предоставьте более подробную информацию. Используете ли вы dataset для заполнения datagrid? Есть ли у вас выделенная объектная модель, которая содержит данные? Под автоматическим заполнением вы подразумеваете, что оно заполняет правильное поле без какого-либо кода с вашей стороны или это только с точки зрения пользователя?

4. В datagrid отображаются данные из базы данных sql. В принципе, когда пользователь дважды щелкает по строке в datagrid, открывается новое окно. В этом окне заголовки из datagrid будут метками с текстовыми полями рядом с ними, отображающими все, что находится в данный момент под этим заголовком. И затем пользователь мог редактировать это содержимое.

5. Вы хотели бы, чтобы форма редактирования автоматически создавала какое-либо поле на основе того, что было в datagrid?

Ответ №1:

Наивным способом справиться с этим было бы создать форму непосредственно внутри события dbl-click из сетки и вручную задать различные поля, отобразить его, получить новое значение и обновить сетку.

Хотя это и будет работать, вероятно, это плохая идея делать слишком много непосредственно в обработчике событий формы… Попробуйте отделить вашу логику и модель домена от вашей формы.

Однако это может дать вам отправную точку…

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

Ответ №2:

Похоже, с этим PropertyGrid могла бы очень хорошо справиться.

Это может помочь вам начать: Получение максимальной отдачи от элемента управления PropertyGrid .NET Framework

Ответ №3:

Ниже приведена очень грубая демонстрация того, как создать редактируемую форму, учитывая только поток данных. Он использует Windows Forms, но, скорее всего, у вас есть DataRow независимо от того, какой фреймворк вы используете. Если вы этого не сделаете, вы можете экстраполировать.

Это демонстрирует, как динамически создавать форму с кучей элементов управления. Он предоставляет простой способ считывания данных после того, как пользователь с ними что-то перепутал.

Чего он не делает, так это не дает вам никаких указаний о том, как проверять и сохранять данные, которые были изменены пользователем. Я дам вам подсказку: прикрепите данные к форме, используйте привязку к текстовым полям и используйте встроенные функции 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;
}