1.功能需求和效果截图
功能需求:两个DataGrid。第一个DataGrid载入员工信息表的数据,第二个DataGrid由combobox选择岗位信息表不同的值(显示值是岗位名称,选择值是岗位ID)显示员工信息表不同的数据。(员工信息表,岗位信息表由员工岗位信息表连接起来,所以第二个DataGrid是要实现多表维护,高级复杂多表查询的功能)
两个按钮。用checkbox选中第一个DataGrid的表的数据,点击第一个按钮,选中的表数据批量增加到第二个DataGrid。选中第二个DataGrid的表的数据,点击第二个按钮,批量删除。
效果截图:
2.实现思路和步骤
第一步:首先要建一个SuperMarket数据库并添加基础数据,创建要用的存储过程。
第二步:实现第一个载入员工信息表的DataGrid。
第三步:实现第二个DataGrid与Combobox,多表维护数据库复杂查询。
第四步:批量增加和批量删除的按钮功能。
2.1数据库SuperMarket
建数据库代码:
use master; go create database SuperMarket go use SuperMarket; go /*==============================================================*/ /* Table: 岗位信息 */ /*==============================================================*/ create table 岗位信息 ( 岗位ID char(6) primary key, 岗位名称 nvarchar(20) ) go /*==============================================================*/ /* Table: 员工信息 */ /*==============================================================*/ create table 员工信息 ( 员工ID char(6) primary key, 员工姓名 nvarchar(20) ) go /*==============================================================*/ /* Table: 员工岗位信息 */ /*==============================================================*/ create table 员工岗位信息 ( ID int identity(1,1) primary key, 员工ID char(6) constraint fk_员工岗位信息_员工ID foreign key references 员工信息(员工ID), 岗位ID char(6) constraint fk_员工岗位信息_岗位ID foreign key references 岗位信息(岗位ID) ) go /*==============================================================*/ /* Table: 供应商信息 */ /*==============================================================*/ create table 供应商信息 ( 供应商ID char(6) primary key, 供应商名称 nvarchar(20) ) go /*==============================================================*/ /* Table: 客户信息 */ /*==============================================================*/ create table 客户信息 ( 客户ID char(6) primary key, 客户名称 nvarchar(20) null ) go /*==============================================================*/ /* Table: 部门信息 */ /*==============================================================*/ create table 部门信息 ( 部门ID char(6) primary key, 部门名称 nvarchar(20) ) go /*==============================================================*/ /* Table: 部门员工信息 */ /*==============================================================*/ create table 部门员工信息 ( ID int identity(1,1) primary key, 员工ID char(6) constraint fk_部门员工信息_员工ID foreign key references 员工信息(员工ID), 部门ID char(6) constraint fk_部门员工信息_部门ID foreign key references 部门信息(部门ID) ) go /*==============================================================*/ /* Table: 商品信息 */ /*==============================================================*/ create table 商品信息 ( 商品ID char(13) primary key, /*EAN-13条码:13位*/ 制造商ID char(6) constraint fk_商品信息_供应商ID foreign key references 供应商信息(供应商ID), 商品名称 nvarchar(20) , 计量单位 nchar(6) ) go /*==============================================================*/ /* Table: 仓库信息 */ /*==============================================================*/ create table 仓库信息 ( 仓库ID char(6) primary key, 仓库名称 nvarchar(20) , 仓库地址 text ) go /*==============================================================*/ /* Table: 库存信息 */ /*==============================================================*/ create table 库存信息 ( 商品ID char(13) primary key,/*商品ID中包含了商品信息、生产厂家、生产时间以及有效期信息,同意名称的商品将有可能采用不同的商品ID*/ 仓库ID char(6) constraint fk_库存信息_仓库ID foreign key references 仓库信息(仓库ID), 入库均价 decimal(12,2) null,/* 库存信息中的入库均价,需要对多次入库时商品的价格进行平均,并且需要考虑计量单位和计量因子*/ 当前数量 decimal(12,2) ,/* 库存信息中的当前数量针对的计量单位只能按《商品信息》表中的计量单位执行 (计量因子=1)*/ constraint fk_库存信息_商品ID foreign key(商品ID) references 商品信息(商品ID) ) go /*==============================================================*/ /* Table: 采购信息 */ /*==============================================================*/ create table 采购信息 ( 采购单ID char(12) primary key, 采购日期 datetime , 采购部门ID char(6) constraint fk_采购信息_采购部门ID foreign key references 部门信息(部门ID), 采购员ID char(6) constraint fk_采购信息_采购员ID foreign key references 员工信息(员工ID), 供应商ID char(6) null constraint fk_采购信息_供应商ID foreign key references 供应商信息(供应商ID), ) go /*==============================================================*/ /* Table: 采购明细 */ /*==============================================================*/ create table 采购明细 ( 采购明细ID UNIQUEIDENTIFIER default(newid()) primary key, 采购单ID char(12) constraint fk_采购明细_采购单ID foreign key references 采购信息(采购单ID), 商品ID char(13) constraint fk_采购明细_商品ID foreign key references 商品信息(商品ID), 计量单位 nchar(6) , /* 采购时的计量单位可以根据实际情况输入 */ 计量因子 decimal(12,2) , /* 计量因子是采购时的计量单位与《商品信息》表中该商品计量单位的比值 */ 采购数量 decimal(12,2) , /* 按采购计量单位计算数量 */ 采购单价 decimal(12,2) /* 按采购计量单位计算数量 */ ) /*==============================================================*/ /* Table: 入库信息 */ /*==============================================================*/ create table 入库信息 ( 入库单ID char(12) primary key, 入库日期 datetime , 库管员ID char(6) constraint fk_入库信息_库管员ID foreign key references 员工信息(员工ID), 入库部门ID char(6) , /*内部入库,如生产部等(产品,半成品) */ 部门代表ID char(6) constraint fk_入库信息_部门代表ID foreign key references 员工信息(员工ID), 采购单ID char(12) null /*采购入库,如采购部等 */ constraint fk_入库信息_采购单ID foreign key references 采购信息(采购单ID), 备注 text null /* 说明入库事由 */ ) go /*==============================================================*/ /* Table: 入库明细 */ /*==============================================================*/ create table 入库明细 ( 入库明细ID UNIQUEIDENTIFIER default(newid()) primary key, 入库单ID char(12) constraint fk_入库明细_入库单ID foreign key references 入库信息(入库单ID), 商品ID char(13) constraint fk_入库明细_商品ID foreign key references 商品信息(商品ID), 入库数量 decimal(12,2) , 入库单价 decimal(12,2) null ) go /*==============================================================*/ /* Table: 销售信息 */ /*==============================================================*/ create table 销售信息 ( 销售单ID char(12) primary key, 销售日期 datetime , 销售部门ID char(6) constraint fk_销售信息_部门ID foreign key references 部门信息(部门ID), 客户ID char(6) constraint fk_销售信息_客户ID foreign key references 客户信息(客户ID) ) go /*==============================================================*/ /* Table: 销售明细 */ /*==============================================================*/ create table 销售明细 ( 销售明细ID UNIQUEIDENTIFIER default(newid()) primary key, 销售单ID char(12) constraint fk_销售明细_销售单ID foreign key references 销售信息(销售单ID), 商品ID char(13) constraint fk_销售明细_商品ID foreign key references 商品信息(商品ID), 销售数量 decimal(12,2) , 销售单价 decimal(12,2) ) /*==============================================================*/ /* Table: 出库信息 */ /*==============================================================*/ create table 出库信息 ( 出库单ID char(12) primary key, 仓库ID char(6), 出库日期 datetime , 出库部门ID char(6) null/*内部领用或调拨出库,如生产部等(半成品) */ constraint fk_出库信息_部门ID foreign key references 部门信息(部门ID), 销售单ID char(12) null/*销售出库,如销售部等 */ constraint fk_出库信息_销售单ID foreign key references 销售信息(销售单ID), 备注 text null/* 说明出库事由 */ ) go /*==============================================================*/ /* Table: 出库明细 */ /*==============================================================*/ create table 出库明细 ( 出库明细ID UNIQUEIDENTIFIER default(newid()) primary key, 出库单ID char(12) constraint fk_出库明细_出库单ID foreign key references 出库信息(出库单ID), 商品ID char(13) constraint fk_出库明细_商品ID foreign key references 商品信息(商品ID), 出库数量 decimal(12,2) , 出库单价 decimal(12,2) null ) go /*==============================================================*/ /* Type: 采购明细临时表 */ /*==============================================================*/ create type 采购明细临时表 as Table ( 商品ID char(13) , 计量单位 nchar(6) , /* 采购时的计量单位可以根据实际情况输入 */ 计量因子 decimal(12,2) , /* 计量因子是采购时的计量单位与《商品信息》表中该商品计量单位的比值 */ 采购数量 decimal(12,2) , /* 按采购计量单位计算数量 */ 采购单价 decimal(12,2) /* 按采购计量单位计算数量 */ ) /*==============================================================*/ /* Type: 入库明细临时表 */ /*==============================================================*/ create type 入库明细临时表 as Table ( 商品ID char(13) , 入库数量 decimal(12,2) ,/* 入库时的计量单位《商品信息》表中该商品计量单位计算,计量因子=1 入库单价*/ 入库单价 decimal(12,2) null/* 入库单价按《商品信息》中该商品计量单位对应的入库价格计算 */ ) Go /*==============================================================*/ /* Type: 出库明细临时表 */ /*==============================================================*/ create type 出库明细临时表 as Table ( 商品ID char(13) , 出库数量 decimal(12,2) , /* 出库数量的计量单位按《商品信息》表中的计量单位计算 */ 出库单价 decimal(12,2) null /* 出库单价按《商品信息》表中的计量单位,以及出库时该商品的库存均价计算 */ ) Go /*==============================================================*/ /* Type: 销售明细临时表 */ /*==============================================================*/ create type 销售明细临时表 as Table ( 商品ID char(13) , 销售数量 decimal(12,2) , /* 销售数量的计量单位按《商品信息》表中的计量单位计算 */ 销售单价 decimal(12,2) null /* 销售单价按《商品信息》表中的计量单位的销售单价计算 */ ) Go use SuperMarket; go insert into 岗位信息 values(‘W0‘,‘经理‘); insert into 岗位信息 values(‘W1‘,‘生产员‘); insert into 岗位信息 values(‘W2‘,‘销售员‘); insert into 岗位信息 values(‘W3‘,‘采购员‘); insert into 岗位信息 values(‘W4‘,‘库管员‘); go insert into 员工信息 values(‘Y00‘,‘张经理‘) insert into 员工信息 values(‘Y01‘,‘生产员1‘); insert into 员工信息 values(‘Y02‘,‘生产员2‘); insert into 员工信息 values(‘Y03‘,‘销售员1‘); insert into 员工信息 values(‘Y04‘,‘销售员2‘); insert into 员工信息 values(‘Y05‘,‘采购员1‘); insert into 员工信息 values(‘Y06‘,‘采购员2‘); insert into 员工信息 values(‘Y07‘,‘库管员1‘); insert into 员工信息 values(‘Y08‘,‘库管员2‘); go insert into 员工岗位信息 values(‘Y00‘,‘W0‘); insert into 员工岗位信息 values(‘Y01‘,‘W1‘); insert into 员工岗位信息 values(‘Y02‘,‘W1‘); insert into 员工岗位信息 values(‘Y03‘,‘W2‘); insert into 员工岗位信息 values(‘Y04‘,‘W2‘); insert into 员工岗位信息 values(‘Y05‘,‘W3‘); insert into 员工岗位信息 values(‘Y06‘,‘W3‘); insert into 员工岗位信息 values(‘Y07‘,‘W4‘); insert into 员工岗位信息 values(‘Y08‘,‘W4‘); go insert into 客户信息 values(‘K01‘,‘匿名‘); insert into 客户信息 values(‘K02‘,‘张三‘); insert into 客户信息 values(‘K03‘,‘李四‘); go insert into 供应商信息 values(‘G01‘,‘伊利‘); insert into 供应商信息 values(‘G02‘,‘蒙牛‘); go insert into 部门信息 values(‘D00‘,‘办公室‘); insert into 部门信息 values(‘D01‘,‘生产部‘); insert into 部门信息 values(‘D02‘,‘销售部‘); insert into 部门信息 values(‘D03‘,‘采购部‘); insert into 部门信息 values(‘D04‘,‘仓储部‘); go insert into 仓库信息 values(‘CK01‘,‘成品仓库1‘,‘地址1‘); insert into 仓库信息 values(‘CK02‘,‘成品仓库2‘,‘地址2‘) go insert into 部门员工信息 values(‘Y00‘,‘D00‘); insert into 部门员工信息 values(‘Y01‘,‘D01‘); insert into 部门员工信息 values(‘Y02‘,‘D01‘); insert into 部门员工信息 values(‘Y03‘,‘D02‘); insert into 部门员工信息 values(‘Y04‘,‘D02‘); insert into 部门员工信息 values(‘Y05‘,‘D03‘); insert into 部门员工信息 values(‘Y06‘,‘D03‘); insert into 部门员工信息 values(‘Y07‘,‘D04‘); insert into 部门员工信息 values(‘Y08‘,‘D04‘); go INSERT INTO 商品信息 VALUES(‘m0001‘,‘G01‘,‘250ML伊利牛奶‘,‘盒‘); INSERT INTO 商品信息 VALUES(‘m0002‘,‘G01‘,‘1000ML伊利牛奶‘,‘盒‘); INSERT INTO 商品信息 VALUES(‘m0003‘,‘G02‘,‘250ML蒙牛牛奶‘,‘盒‘); INSERT INTO 商品信息 VALUES(‘m0004‘,‘G02‘,‘1000ML蒙牛牛奶‘,‘盒‘); go
存储过程代码:
use SuperMarket; go create proc 查询全体员工 as select 员工ID,员工姓名 from 员工信息 go use SuperMarket; go create proc 查询全体岗位信息 as select 岗位ID,岗位名称 from 岗位信息 go create proc 根据岗位ID查询员工 @岗位ID char(6) as begin select c.员工ID, A.员工姓名 from 员工岗位信息 as C inner join 员工信息 as A on C.员工ID=A.员工ID inner join 岗位信息 as B on C.岗位ID=B.岗位ID where C.岗位ID=@岗位ID; end go use SuperMarket; go create proc 增加员工岗位信息 @员工ID char(6), @岗位ID char(6) as begin DECLARE @errorSum int; set @errorSum=0; begin transaction if(NOT EXISTS(select * from 员工岗位信息 where 员工ID=@员工ID and 岗位ID=@岗位ID)) begin insert into 员工岗位信息 values(@员工ID ,@岗位ID); end if @errorSum<>0 rollback transaction; else commit transaction; end go use SuperMarket; go create proc 删除员工岗位信息 @员工ID char(6), @岗位ID char(6) as begin DECLARE @errorSum int; set @errorSum=0; begin transaction if(EXISTS(select * from 员工岗位信息 where 员工ID=@员工ID and 岗位ID=@岗位ID)) begin delete from 员工岗位信息 where 员工ID=@员工ID and 岗位ID=@岗位ID end if @errorSum<>0 rollback transaction; else commit transaction; end go
然后回到Visual Studio来,建一个接口类员工信息.cs。
在接口实现方法DB员工信息里建连接数据库的字符串。
public class DB员工信息 : I员工信息 { private SqlConnection conn; public DB员工信息() { string str = @"Data Source=PC01;Integrated Security=SSPI;database=SuperMarket"; conn = new SqlConnection(str); } }
2.2 实现第一个载入员工信息表的DataGrid
前台MainWindow.xaml:
<DataGrid AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" Height="290" HorizontalAlignment="Left" Margin="44,48,0,0" Name="dataGrid1" VerticalAlignment="Top" Width="184" RowDetailsVisibilityMode="Visible" SelectionMode="Single" IsReadOnly="True" > <DataGrid.Columns> <DataGridTemplateColumn Header="序号"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox Click="CheckBox1_Click" Tag="{Binding 员工ID}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="员工ID" Binding="{Binding 员工ID, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" x:Name="dataGrid员工ID" /> <DataGridTextColumn Header="员工姓名" Binding="{Binding 员工姓名, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" /> </DataGrid.Columns> </DataGrid>
后台
dataGrid1.ItemsSource = daL.get员工信息DataSet().Tables["员工信息"].DefaultView;
对应的C#存储过程代码(在接口的接口实现方法里)
public DataSet get员工信息DataSet() { DataSet ds = new DataSet(); if (conn == null) return null; SqlCommand cmd = new SqlCommand("查询全体员工", conn); cmd.CommandType = CommandType.StoredProcedure;//存储过程带参数的使用的代码 SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(ds, "员工信息"); return ds; }
2.3 实现第二个DataGrid与Combobox,多表维护数据库复杂查询。
前台:
<GroupBox Header="岗位信息" Height="78" HorizontalAlignment="Left" Margin="452,34,0,0" Name="groupBox1" VerticalAlignment="Top" Width="188"> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="107*" /> <ColumnDefinition Width="96*" /> </Grid.ColumnDefinitions> <ComboBox Height="23" HorizontalAlignment="Left" Margin="18,14,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" Grid.ColumnSpan="2" Loaded="comboBox1_Loaded" SelectionChanged="comboBox1_SelectionChanged" /> </Grid> </GroupBox> <DataGrid AutoGenerateColumns="False" IsSynchronizedWithCurrentItem="True" Height="255" HorizontalAlignment="Left" Margin="456,118,0,0" Name="dataGrid2" VerticalAlignment="Top" Width="184" RowDetailsVisibilityMode="Visible" SelectionMode="Single" IsReadOnly="True" > <DataGrid.Columns> <DataGridTemplateColumn Header="序号"> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <CheckBox Click="CheckBox2_Click" Tag="{Binding 员工ID}"></CheckBox> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn> <DataGridTextColumn Header="员工ID" Binding="{Binding 员工ID, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" x:Name="dataGrid员工ID2" /> <DataGridTextColumn Header="员工姓名" Binding="{Binding 员工姓名, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" x:Name="dataGridComboBox2"/> </DataGrid.Columns> </DataGrid>
后台:(岗位ID是自己定义的一个string类型的字符串,用来存放combobox选中取得的岗位ID,即SelectedValue取得的值)
private void comboBox1_SelectionChanged(object sender, SelectionChangedEventArgs e) { 岗位ID = this.comboBox1.SelectedValue.ToString(); dataGrid2.ItemsSource = null; dataGrid2.ItemsSource = daL.根据岗位ID查询员工(岗位ID).Tables["岗位信息"].DefaultView; } private void comboBox1_Loaded(object sender, RoutedEventArgs e) { DataSet ds = daL.get岗位信息DataSet(); this.comboBox1.ItemsSource = ds.Tables["岗位信息"].DefaultView; this.comboBox1.DisplayMemberPath = "岗位名称";//显示的信息 this.comboBox1.SelectedValuePath = "岗位ID"; //根据显示的信息取得选中的ID }
对应的C#存储过程代码(在接口的接口实现方法里)
public DataSet get岗位信息DataSet() { DataSet ds = new DataSet(); if (conn == null) return null; SqlCommand cmd = new SqlCommand("查询全体岗位信息", conn); cmd.CommandType = CommandType.StoredProcedure;//存储过程带参数的使用的代码 SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(ds, "岗位信息"); return ds; } public DataSet 根据岗位ID查询员工(string 岗位ID) { DataSet ds = new DataSet(); if (conn == null) return null; SqlCommand cmd = new SqlCommand("根据岗位ID查询员工", conn); cmd.Parameters.Add(new SqlParameter("@岗位ID", SqlDbType.Char, 6)).Value = 岗位ID; cmd.CommandType = CommandType.StoredProcedure;//存储过程带参数的使用的代码 SqlDataAdapter da = new SqlDataAdapter(cmd); da.Fill(ds, "岗位信息"); return ds; }
2.4 批量增加和批量删除的按钮功能。
前台:
<Button Content=">>" Height="40" HorizontalAlignment="Left" Margin="302,72,0,0" Name="button1" VerticalAlignment="Top" Width="75" Click="button1_Click" /> <Button Content="<<" Height="43" HorizontalAlignment="Left" Margin="302,0,0,136" Name="button2" VerticalAlignment="Bottom" Width="75" Click="button2_Click" />
CheckBox1选择框代码(取得员工信息表每一行对应的员工ID)首先设一个LIST1(MultiSelectList1)集合存放ID,然后设置一个员工ID1存放取得的ID,然后把员工ID1放在LIST集合里。
private void CheckBox1_Click(object sender, RoutedEventArgs e) { CheckBox dg = sender as CheckBox; try { string 员工ID1 = dg.Tag.ToString(); //获取该行的FID var bl = dg.IsChecked; //MessageBox.Show(员工ID); if (bl == true) { MultiSelectList1.Add(员工ID1); //如果选中就保存FID } else { MultiSelectList1.Remove(员工ID1); //如果选中取消就删除里面的FID } } catch { Exception ex; } }
CheckBox2选择框代码(取得员工信息表每一行对应的员工ID)首先设一个LIST2(MultiSelectList2)集合存放ID,然后设置一个员工ID2存放取得的ID,然后把员工ID2放在LIST集合里。
private void CheckBox2_Click(object sender, RoutedEventArgs e) { CheckBox dg = sender as CheckBox; try { string 员工ID2 = dg.Tag.ToString(); //获取该行的FID var bl = dg.IsChecked; //MessageBox.Show(员工ID); if (bl == true) { MultiSelectList2.Add(员工ID2); //如果选中就保存FID } else { MultiSelectList2.Remove(员工ID2); //如果选中取消就删除里面的FID } } catch { Exception ex; } }
后台:
private void button1_Click(object sender, RoutedEventArgs e) { foreach (string 员工ID1 in MultiSelectList1) { daL.Insert员工岗位(员工ID1, 岗位ID);//插入 dataGrid2.ItemsSource = daL.根据岗位ID查询员工(岗位ID).Tables["岗位信息"].DefaultView; } } private void button2_Click(object sender, RoutedEventArgs e) { foreach (string 员工ID2 in MultiSelectList2) { daL.Delete员工岗位(员工ID2, 岗位ID);//删除 dataGrid2.ItemsSource = daL.根据岗位ID查询员工(岗位ID).Tables["岗位信息"].DefaultView; } MultiSelectList2.Clear(); }
对应的C#存储过程代码(在接口的接口实现方法里)
public void Insert员工岗位(string 员工ID, string 岗位ID) { DataSet ds = new DataSet(); if (conn == null) return; SqlCommand cmd = new SqlCommand("增加员工岗位信息", conn); cmd.Parameters.Add(new SqlParameter("@员工ID", SqlDbType.Char, 6)).Value = 员工ID; //输入参数 cmd.Parameters.Add(new SqlParameter("@岗位ID", SqlDbType.NChar, 20)).Value = 岗位ID; //输入参数 cmd.CommandType = CommandType.StoredProcedure; if (conn.State == ConnectionState.Closed) conn.Open(); try { cmd.ExecuteNonQuery(); } catch (Exception ex) { } } public void Delete员工岗位(string 员工ID, string 岗位ID) { DataSet ds = new DataSet(); if (conn == null) return; SqlCommand cmd = new SqlCommand("删除员工岗位信息", conn); cmd.Parameters.Add(new SqlParameter("@员工ID", SqlDbType.Char, 6)).Value = 员工ID; //输入参数 cmd.Parameters.Add(new SqlParameter("@岗位ID", SqlDbType.NChar, 20)).Value = 岗位ID; //输入参数 cmd.CommandType = CommandType.StoredProcedure; if (conn.State == ConnectionState.Closed) conn.Open(); try { cmd.ExecuteNonQuery(); } catch (Exception ex) { } }