Как реализовать автоматическое обновление listView win forms c#?
Суть в том, что при нажатии кнопки добавить должно сразу же отображаться поле в richtextbox
, а получается что только при следующем добавлении поля, ранее добавленное поле отображается в виде запроса, а второе соответственно нет и так далее. Можно ли изменить это как-либо, уже пробовал делать многое, что-то не получается.
Главный метод UpdateSQLQuery
. Еще важный момент, может есть какой-нибудь метод который сразу же обновляется при изменении в DataGridView
и выводит нам незамедлительно результат. В общем, нужна помощь более опытного.
Архив проекта прикреплю.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.IO;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Threading;
using System.Web;
using System.Data.SQLite;
using static System.Windows.Forms.VisualStyles.VisualStyleElement;
using System.Reflection.Emit;
namespace DB_Broser_for_SQLite
{
public partial class CreateTableForm : Form
{
public event Action<string> DataPassed;
private string tableName;
private DataTable schema;
private bool isEditMode = false;
private string dbFilePath;
public CreateTableForm(string dbFilePath)
{
InitializeComponent();
InitializeDataGridView();
textBox1.TextChanged += textBox1_TextChanged;// Подключаем обработчик событий
dataGridView1.CellValueChanged += dataGridView1_CellValueChanged;
dataGridView1.CellContentClick += dataGridView1_CellContentClick;// Подключаем обработчик событий
this.dbFilePath = dbFilePath;
// Здесь можно добавить код для работы с базой данных
}
public void SetButtonText(string text)
{
button1.Text = text;
}
public void SetEditMode(string buttonText, DataTable schema, string tableName)
{
button1.Text = buttonText; // Change button text to "Изменить"
this.tableName = tableName; // Store the table name
this.isEditMode = true; // Set edit mode to true
LoadTableDataFromSchema(schema, tableName); // Load existing schema data into the form fields
}
public class TableField
{
public string Name { get; set; }
public string Type { get; set; }
public bool IsNotNull { get; set; }
}
private void dataGridView1_CellContentClick(object sender, DataGridViewCellEventArgs e)
{
}
private void toolStripButton1_Click(object sender, EventArgs e)
{
int newRowIndex = dataGridView1.Rows.Add();
DataGridViewRow newRow = dataGridView1.Rows[newRowIndex];
newRow.Cells["Name"].Value = "Field" + (newRowIndex + 1); // Условное имя поля
newRow.Cells["Type"].Value = "INTEGER"; // Тип данных
//UpdateSQLQuery();
}
private void richTextBox1_TextChanged(object sender, EventArgs e)
{
}
private void InitializeDataGridView()
{
dataGridView1.Columns.Clear(); // Очищаем предыдущие столбцы, если они есть
dataGridView1.Columns.Add(new DataGridViewTextBoxColumn { Name = "Name", HeaderText = "Имя" });
// Добавляем ComboBox для типов данных
var typeColumn = new DataGridViewComboBoxColumn
{
Name = "Type",
HeaderText = "Тип",
DataSource = new List<string> { "INTEGER", "TEXT", "REAL", "BLOB" } // Пример типов данных
};
dataGridView1.Columns.Add(typeColumn);
// Добавляем CheckBox для Not Null
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn { Name = "NotNull", HeaderText = "Not Null" });
// Добавляем CheckBox для Primary Key
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn { Name = "PrimaryKey", HeaderText = "Первичный ключ" });
// Добавляем CheckBox для Auto Increment
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn { Name = "AutoIncrement", HeaderText = "Автокремент" });
// Добавляем CheckBox для Unique
dataGridView1.Columns.Add(new DataGridViewCheckBoxColumn { Name = "Unique", HeaderText = "Уникальный" });
}
private void textBox1_TextChanged(object sender, EventArgs e)
{
UpdateSQLQuery();
}
private void UpdateSQLQuery()
{
string tableName = textBox1.Text.Trim();
if (!string.IsNullOrEmpty(tableName))
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("CREATE TABLE \"{0}\" (\n", tableName);
List<string> fields = new List<string>();
string primaryKey = null;
bool hasPrimaryKey = false;
for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) // -1 чтобы избежать пустой строки
{
var row = dataGridView1.Rows[i];
string fieldName = row.Cells["Name"].Value?.ToString();
string fieldType = row.Cells["Type"].Value?.ToString();
bool isNotNull = row.Cells["NotNull"].Value != null && (bool)row.Cells["NotNull"].Value;
bool isPrimaryKey = row.Cells["PrimaryKey"].Value != null && (bool)row.Cells["PrimaryKey"].Value;
bool isAutoIncrement = row.Cells["AutoIncrement"].Value != null && (bool)row.Cells["AutoIncrement"].Value;
bool isUnique = row.Cells["Unique"].Value != null && (bool)row.Cells["Unique"].Value;
if (!string.IsNullOrEmpty(fieldName) && !string.IsNullOrEmpty(fieldType))
{
var fieldDefinition = new StringBuilder();
fieldDefinition.AppendFormat(" \"{0}\" {1}", fieldName, fieldType);
if (isNotNull)
{
fieldDefinition.Append(" NOT NULL");
}
if (isUnique)
{
fieldDefinition.Append(" UNIQUE");
}
fields.Add(fieldDefinition.ToString());
// Проверяем на первичный ключ
if (isPrimaryKey)
{
if (isAutoIncrement)
{
primaryKey = $"PRIMARY KEY(\"{fieldName}\" AUTOINCREMENT)";
}
else
{
primaryKey = $"PRIMARY KEY(\"{fieldName}\")";
}
hasPrimaryKey = true;
}
}
}
// Добавляем все поля в StringBuilder с запятой между ними
if (fields.Count > 0)
{
sb.AppendLine(string.Join(",\n", fields) + ",");
}
// Если есть первичный ключ, добавляем его без лишней запятой
if (hasPrimaryKey && !string.IsNullOrEmpty(primaryKey))
{
sb.AppendLine(primaryKey);
}
sb.Append(");");
richTextBox1.Text = sb.ToString();
}
else
{
richTextBox1.Text = string.Empty; // Очистка RichTextBox, если поле пустое
}
}
private void dataGridView1_CellValueChanged(object sender, DataGridViewCellEventArgs e)
{
// Обновляем SQL-запрос после изменения значения
UpdateSQLQuery();
if (e.RowIndex >= 0 && (e.ColumnIndex == 3 || e.ColumnIndex == 4)) // 3 - PrimaryKey, 4 - AutoIncrement
{
var row = dataGridView1.Rows[e.RowIndex];
// Обработка изменения AutoIncrement
if (e.ColumnIndex == 4) // AutoIncrement
{
bool isAutoIncrementChecked = row.Cells["AutoIncrement"].Value != null && (bool)row.Cells["AutoIncrement"].Value;
if (isAutoIncrementChecked)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (r.Index != e.RowIndex && (r.Cells["AutoIncrement"].Value != null && (bool)r.Cells["AutoIncrement"].Value))
{
r.Cells["AutoIncrement"].Value = false; // Убираем отметку с другого AutoIncrement
}
}
}
}
// Обработка изменения PrimaryKey
if (e.ColumnIndex == 3) // PrimaryKey
{
bool isPrimaryKeyChecked = row.Cells["PrimaryKey"].Value != null && (bool)row.Cells["PrimaryKey"].Value;
if (isPrimaryKeyChecked)
{
foreach (DataGridViewRow r in dataGridView1.Rows)
{
if (r.Index != e.RowIndex && (r.Cells["PrimaryKey"].Value != null && (bool)r.Cells["PrimaryKey"].Value))
{
r.Cells["PrimaryKey"].Value = false; // Убираем отметку с другого PrimaryKey
}
}
}
}
// Устанавливаем PrimaryKey для текущей строки, если AutoIncrement установлен
if (row.Cells["AutoIncrement"].Value != null && (bool)row.Cells["AutoIncrement"].Value)
{
row.Cells["PrimaryKey"].Value = true; // Устанавливаем PrimaryKey для текущей строки
}
}
}
public void LoadTableDataFromSchema(DataTable schemaTable, string tableName)
{
// Set the table name in textBox1
textBox1.Text = tableName;
// Clear existing rows in the DataGridView
dataGridView1.Rows.Clear();
// Populate the DataGridView with the schema data
foreach (DataRow row in schemaTable.Rows)
{
int newRowIndex = dataGridView1.Rows.Add();
DataGridViewRow newRow = dataGridView1.Rows[newRowIndex];
// Fill in the DataGridView cells with the schema information
newRow.Cells["Name"].Value = row["name"]; // Column name
newRow.Cells["Type"].Value = row["type"]; // Data type
// Check for NOT NULL constraint
newRow.Cells["NotNull"].Value = row["notnull"].ToString() == "1"; // 1 indicates NOT NULL
// Check for PRIMARY KEY constraint
newRow.Cells["PrimaryKey"].Value = row["pk"].ToString() == "1"; // 1 indicates PRIMARY KEY
// Auto Increment is not directly available, but can be inferred if it's a PRIMARY KEY and INTEGER
newRow.Cells["AutoIncrement"].Value = (row["pk"].ToString() == "1" && row["type"].ToString().ToUpper().Contains("INTEGER"));
// Unique constraint is not directly available, consider adding a separate logic if needed
newRow.Cells["Unique"].Value = false; // Default to false, adjust as necessary
}
// Update the SQL query based on the loaded schema
UpdateSQLQuery(); // Call this to reflect the loaded data in the SQL query box
// Set the SQL code in richTextBox1
richTextBox1.Text = GenerateCreateTableSQL(schemaTable, tableName);
}
private string GenerateCreateTableSQL(DataTable schemaTable, string tableName)
{
StringBuilder sb = new StringBuilder();
sb.AppendFormat("CREATE TABLE \"{0}\" (\n", tableName);
List<string> fields = new List<string>();
string primaryKey = null;
bool hasPrimaryKey = false;
foreach (DataRow row in schemaTable.Rows)
{
string fieldName = row["name"].ToString();
string fieldType = row["type"].ToString();
bool isNotNull = row["notnull"].ToString() == "1";
bool isPrimaryKey = row["pk"].ToString() == "1";
bool isAutoIncrement = isPrimaryKey && fieldType.ToUpper().Contains("INTEGER");
var fieldDefinition = new StringBuilder();
fieldDefinition.AppendFormat(" \"{0}\" {1}", fieldName, fieldType);
if (isNotNull)
{
fieldDefinition.Append(" NOT NULL");
}
if (isPrimaryKey)
{
if (isAutoIncrement)
{
primaryKey = $"PRIMARY KEY(\"{fieldName}\" AUTOINCREMENT)";
}
else
{
primaryKey = $"PRIMARY KEY(\"{fieldName}\")";
}
hasPrimaryKey = true;
}
fields.Add(fieldDefinition.ToString());
}
if (fields.Count > 0)
{
sb.AppendLine(string.Join(",\n", fields) + ",");
}
if (hasPrimaryKey && !string.IsNullOrEmpty(primaryKey))
{
sb.AppendLine(primaryKey);
}
sb.Append(");");
return sb.ToString();
}
private void button1_Click(object sender, EventArgs e)
{
if (isEditMode)
{
SaveChangesToTable();
this.Close();
}
else
{
// Получаем SQL-запрос из RichTextBox
string sql = richTextBox1.Text;
// Проверяем, не пустой ли SQL-запрос
if (string.IsNullOrWhiteSpace(sql))
{
MessageBox.Show("Пожалуйста, введите SQL-запрос.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
return;
}
// Выполняем SQL-запрос
ExecuteSQL(sql);
// Закрываем форму после выполнения запроса (по желанию)
this.Close();
}
}
private void SaveChangesToTable()
{
using (var connection = new SQLiteConnection($"Data Source={dbFilePath};Version=3;"))
{
connection.Open();
// Получаем новое имя таблицы из textBox1
string newTableName = textBox1.Text.Trim();
// Проверяем, изменилось ли имя таблицы
if (newTableName != tableName)
{
// Переименовываем таблицу
string renameTableQuery = $"ALTER TABLE \"{tableName}\" RENAME TO \"{newTableName}\";";
using (var renameCommand = new SQLiteCommand(renameTableQuery, connection))
{
renameCommand.ExecuteNonQuery();
}
tableName = newTableName; // Обновляем локальную переменную tableName
}
// Получаем список существующих столбцов
var existingColumns = new HashSet<string>();
using (var schemaCommand = new SQLiteCommand($"PRAGMA table_info(\"{tableName}\");", connection))
using (var reader = schemaCommand.ExecuteReader())
{
while (reader.Read())
{
existingColumns.Add(reader["name"].ToString());
}
}
// Теперь сохраняем изменения в полях
foreach (DataGridViewRow row in dataGridView1.Rows)
{
if (row.IsNewRow) continue; // Пропускаем пустую строку
string fieldName = row.Cells["Name"].Value?.ToString();
string fieldType = row.Cells["Type"].Value?.ToString();
bool isNotNull = row.Cells["NotNull"].Value != null && (bool)row.Cells["NotNull"].Value;
bool isPrimaryKey = row.Cells["PrimaryKey"].Value != null && (bool)row.Cells["PrimaryKey"].Value;
bool isAutoIncrement = row.Cells["AutoIncrement"].Value != null && (bool)row.Cells["AutoIncrement"].Value;
bool isUnique = row.Cells["Unique"].Value != null && (bool)row.Cells["Unique"].Value;
// Проверяем, существует ли уже столбец
if (!existingColumns.Contains(fieldName))
{
// Строим запрос ALTER TABLE для добавления новых полей
StringBuilder addFieldQuery = new StringBuilder($"ALTER TABLE \"{tableName}\" ADD COLUMN \"{fieldName}\" {fieldType}");
if (isNotNull)
{
addFieldQuery.Append(" NOT NULL");
}
if (isUnique)
{
addFieldQuery.Append(" UNIQUE");
}
if (isPrimaryKey)
{
addFieldQuery.Append(" PRIMARY KEY");
}
if (isAutoIncrement)
{
addFieldQuery.Append(" AUTOINCREMENT");
}
using (var addFieldCommand = new SQLiteCommand(addFieldQuery.ToString(), connection))
{
addFieldCommand.ExecuteNonQuery();
}
// Добавляем новый столбец в список существующих столбцов
existingColumns.Add(fieldName);
}
}
MessageBox.Show("Изменения успешно сохранены.", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
private void ExecuteSQL(string sql)
{
try
{
using (var connection = new SQLiteConnection($"Data Source={dbFilePath};Version=3;")) // Используйте ваш тип базы данных
{
connection.Open();
using (var command = new SQLiteCommand(sql, connection))
{
command.ExecuteNonQuery(); // Выполняем SQL-запрос
}
}
MessageBox.Show("Таблица успешно создана!", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
catch (Exception ex)
{
MessageBox.Show($"Ошибка при выполнении запроса: {ex.Message}", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
private void dataGridView1_CurrentCellDirtyStateChanged(object sender, EventArgs e)
{
if (dataGridView1.IsCurrentCellDirty)
{
// Фиксируем изменения в текущей ячейке
dataGridView1.CommitEdit(DataGridViewDataErrorContexts.Commit);
UpdateSQLQuery();
}
}
private void toolStripButton2_Click(object sender, EventArgs e)
{
// Проверяем, есть ли выбранные строки
if (dataGridView1.SelectedRows.Count > 0)
{
foreach (DataGridViewRow selectedRow in dataGridView1.SelectedRows)
{
if (!selectedRow.IsNewRow) // Убедитесь, что это не новая строка
{
// Получаем имя поля для удаления
string fieldName = selectedRow.Cells["Name"].Value.ToString();
dataGridView1.Rows.Remove(selectedRow); // Удаляем строку из DataGridView
// Удаляем поле из базы данных
RemoveFieldFromDatabase(fieldName);
}
}
// Обновляем SQL-запрос после удаления
UpdateSQLQuery();
}
else
{
MessageBox.Show("Пожалуйста, выберите поле для удаления.", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
private void RemoveFieldFromDatabase(string fieldName)
{
using (var connection = new SQLiteConnection($"Data Source={dbFilePath};Version=3;"))
{
connection.Open();
// Получаем текущее имя таблицы
string currentTableName = tableName;
// Получаем схему текущей таблицы
var schemaTable = new DataTable();
using (var schemaCommand = new SQLiteCommand($"PRAGMA table_info(\"{currentTableName}\");", connection))
using (var reader = schemaCommand.ExecuteReader())
{
schemaTable.Load(reader);
}
// Создаем новую таблицу с необходимыми полями
var createTableQuery = new StringBuilder();
createTableQuery.AppendFormat("CREATE TABLE \"new_{0}\" (", currentTableName);
List<string> fields = new List<string>();
foreach (DataRow row in schemaTable.Rows)
{
string name = row["name"].ToString();
if (name != fieldName) // Пропускаем удаляемое поле
{
string type = row["type"].ToString();
bool isNotNull = row["notnull"].ToString() == "1";
bool isPrimaryKey = row["pk"].ToString() == "1";
var fieldDefinition = new StringBuilder();
fieldDefinition.AppendFormat(" \"{0}\" {1}", name, type);
if (isNotNull) fieldDefinition.Append(" NOT NULL");
fields.Add(fieldDefinition.ToString());
}
}
if (fields.Count > 0)
{
createTableQuery.AppendLine(string.Join(",\n", fields));
}
createTableQuery.Append(");");
// Создаем новую таблицу
using (var createCommand = new SQLiteCommand(createTableQuery.ToString(), connection))
{
createCommand.ExecuteNonQuery();
}
// Копируем данные из старой таблицы в новую
var insertQuery = new StringBuilder();
insertQuery.AppendFormat("INSERT INTO \"new_{0}\" ({1}) SELECT {1} FROM \"{0}\";",
currentTableName, string.Join(", ", fields.Select(f => f.Split(' ')[0]))); // Выбираем только имена полей
using (var insertCommand = new SQLiteCommand(insertQuery.ToString(), connection))
{
insertCommand.ExecuteNonQuery();
}
// Удаляем старую таблицу
using (var dropCommand = new SQLiteCommand($"DROP TABLE \"{currentTableName}\";", connection))
{
dropCommand.ExecuteNonQuery();
}
// Переименовываем новую таблицу
using (var renameCommand = new SQLiteCommand($"ALTER TABLE \"new_{currentTableName}\" RENAME TO \"{currentTableName}\";", connection))
{
renameCommand.ExecuteNonQuery();
}
MessageBox.Show($"Поле \"{fieldName}\" успешно удалено.", "Успех", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
}
}
}
Код второй формы, где нужно все создается таблица.
Ответы (1 шт):
Я нашел решение в этой строчке кода. Моя ошибка. for (int i = 0; i < dataGridView1.Rows.Count - 1; i++) - это неправильно. Нужно for (int i = 0; i < dataGridView1.Rows.Count; i++) и тогда все будет так как надо. Работайте через дебаг он помогает.