#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;
}