c# - 在 WPF DataGrid 中删除行和更改数据时遇到问题(使用 MySQL)
问题描述
我正在尝试制作一个以数据网格为中心的 WPF 应用程序。我有以下 MySQL 表:
+-------------+-----------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+-------------+-----------------+------+-----+---------+----------------+
| id | int(6) unsigned | NO | PRI | NULL | auto_increment |
| DQvalue | varchar(255) | YES | | NULL | |
| DQIndexOf | varchar(255) | YES | | NULL | |
| DIvalue | varchar(255) | YES | | NULL | |
| DIIndexOf | varchar(255) | YES | | NULL | |
| AQvalue | varchar(255) | YES | | NULL | |
| AQIndexOf | varchar(255) | YES | | NULL | |
| AIvalueLoHi | varchar(255) | YES | | NULL | |
| AIIndexOf | varchar(255) | YES | | NULL | |
| description | text | YES | | NULL | |
| checkBit | tinyint(1) | NO | | NULL | |
| GND1 | tinyint(1) | NO | | NULL | |
| GND2 | tinyint(1) | NO | | NULL | |
+-------------+-----------------+------+-----+---------+----------------+
这是 DataGrid XAML:
<DataGrid ItemsSource="{Binding Path=., Mode=TwoWay}" x:Name="receptenDg" AutoGeneratedColumns="resize_plugdatagrid" HorizontalAlignment="Left" Height="894" Margin="10,10,0,0" VerticalAlignment="Top" Width="1543" Grid.ColumnSpan="3">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Delete">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button x:Name="delete" Content="Delete" Click="Delete_Row"/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
<DataGrid.ColumnHeaderStyle>
<Style TargetType="{x:Type DataGridColumnHeader}">
<Setter Property="Background" Value="{StaticResource PrimaryBrush}"/>
<Setter Property="Foreground" Value="{StaticResource PrimaryFont}" />
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="BorderThickness" Value="3"/>
<Setter Property="BorderBrush" Value="Black"/>
</Style>
</DataGrid.ColumnHeaderStyle>
</DataGrid>
我还制作了一个 Mysql 数据库类以在整个 WPF 应用程序中使用。
当我的 WPF 应用程序启动时,以下代码被初始化:
DataContext = this;
receptenDg.BeginInit();
db.CreateTable();
db.dt.Tables[0].RowDeleted += Row_Deleted;
db.dt.Tables[0].RowChanged += Row_Changed;
receptenDg.SetBinding(ItemsControl.ItemsSourceProperty, new Binding
{
Source = db.dt.Tables[0]
});
receptenDg.Items.Refresh();
receptenDg.EndInit();
应用程序的这部分工作正常。这段代码用我的 MySQL 数据库中的数据正确地填充了我的数据网格。当我单击一个按钮时,我会打开第二个窗口。我输入了一些信息,单击第二个窗口内的一个按钮,它在我的 mysql 表中添加了一个新行。之后它关闭了我的第二个窗口。
像这样关闭窗口后,我在我的数据库类中尝试了以下函数:
ReceptenPopup recept = new ReceptenPopup();
if (recept.ShowDialog() == true)
{
}
else
{
receptenDg.BeginInit();
db.Update();
db.CreateTable();
receptenDg.SetBinding(ItemsControl.ItemsSourceProperty, new Binding
{
Source = db.dt.Tables[0]
});
receptenDg.Items.Refresh();
receptenDg.EndInit();
}
else 语句中的代码在我的数据库类中调用以下函数(db 是对我的 MySQL 类的调用):
public DataSet dt;
public DataSet Update()
{
MySqlCommandBuilder myBuilder = new MySqlCommandBuilder(adp);
adp.Update(dt);
return dt;
}
public DataSet CreateTable()
{
string query = "Select * from Recepten";
using(MySqlConnection conn0 = new MySqlConnection(connectionString))
using(MySqlCommand cmd = new MySqlCommand(query, conn0))
using(adp = new MySqlDataAdapter(cmd))
{
dt = new DataSet();
adp.Fill(dt);
}
return dt;
}
虽然我现在可以向我的数据网格添加新行,但无法删除以前有效的行。这是我用来从我的数据网格中删除一行的函数。
private void Delete_Row(object sender, RoutedEventArgs e)
{
DataRowView row = (DataRowView)receptenDg.SelectedItem;
db.dt.Tables[0].Rows.Remove(row.Row);
//dt.Rows.Remove(row.Row);
db.Update();
receptenDg.Items.Refresh();
}
我之前还使用了绑定到我的初始化代码的以下函数(请参阅上面的初始化代码)。我以前使用过 DataTable,但后来改用 DataSet,因为它不那么麻烦(个人)。
private void Row_Changed(object sender, DataRowChangeEventArgs e)
{
updateDataGrid();
}
private void Row_Deleted(object sender, DataRowChangeEventArgs e)
{
updateDataGrid();
}
private void updateDataGrid()
{
receptenDg.BeginInit();
db.Update();
db.CreateTable();
receptenDg.SetBinding(ItemsControl.ItemsSourceProperty, new Binding
{
Source = db.dt.Tables[0]
});
receptenDg.Items.Refresh();
receptenDg.EndInit();
}
当我以前使用 DataTable 时,上面的函数就像一个魅力,但我似乎无法让这些函数再次工作。
对不起我糟糕的英语。
解决方案
我设法解决了我的问题。我在我的初始化代码中添加了以下内容:
DataContext = this;
receptenDg.BeginInit();
db.CreateTable();
receptenDg.SetBinding(ItemsControl.ItemsSourceProperty, new Binding
{
Source = db.dt.Tables[0]
});
receptenDg.AutoGenerateColumns = true;
receptenDg.CanUserAddRows = false;
db.dt.Tables[0].RowChanged += new DataRowChangeEventHandler(Row_Changed);
db.dt.Tables[0].RowDeleted += new DataRowChangeEventHandler(Row_Deleted);
receptenDg.Items.Refresh();
receptenDg.EndInit();
注意 Row_Changed 和 RowDeleted 添加。他们在数据网格内部发生变化时调用以下函数:
#region This function updates the datatable when a row has been altered in the datagrid.
private void Row_Changed(object sender, DataRowChangeEventArgs e)
{
db.Update();
}
#endregion
#region This function updates the datatable when a row has been deleted in the datagrid.
private void Row_Deleted(object sender, DataRowChangeEventArgs e)
{
db.Update();
}
#endregion
//db.Update calls a function inside my MySQL Code, which looks like this:
public DataSet Update()
{
string query = "Select * from Recepten";
using (MySqlConnection cnn = new MySqlConnection(connectionString))
using (MySqlCommand cmd4 = new MySqlCommand(query,cnn))
using(adp = new MySqlDataAdapter(cmd4))
using (MySqlCommandBuilder myBuilder = new MySqlCommandBuilder(adp))
{
cnn.Open();
adp.Update(dt);
}
return dt;
}
推荐阅读
- javascript - 在 Jquery 中单击“href”标签时加载配音
- android-studio-3.0 - 登录活动不是封闭类
- java - 使用 GSON 解析一个对象数组,该数组包含一个包含所需字符串的对象
- gcc - GCC 无法编译任何内容(甚至是空文件)并出现错误:“pthread_mutex_timedlock”未在此范围内声明
- php - Laravel setLocale 返回存储的值,但使用 config.app 默认值
- c# - 使用 Moq 将用户添加到角色
- java - 未捕获的 DOMException:无法在“节点”上执行“removeChild”:要删除的节点不是该节点的子节点
- php - 文件导入到 mySQLi - 不工作
- java - 在多个滚动中的 iframe 内滚动
- windows - Windows 10 Docker 容器客户端无法访问主机上的 SQL