C#Windows窗体期末大作业笔记

目录

一、窗体转换

转到新窗体

回到旧窗体

二、数据库操作·脱机模式

查询一个数据

新增或修改数据

查询多个数据

三、限制输入的字符类型

常用函数

如果是为了密码做限制功能

四、让tabcontrol的其中一个页面不可见

方法一

方法二

方法三

五、一点sql语句

查询借书记录,并从图书表格调出书的具体信息,最后把这些东西合成一个表

六、出现的一些错误

System.Data.SqlClient.SqlException:“字符串或二进制数据将在表“library.dbo.userInfo”,列“Passwords”中被截断。截断值:“System.Windows.F”。

comm.ExecuteScalar().ToString()报错

查询结果比预期结果多空格,导致判断出错

七、杂记·一些属性

给label里的文字加下划线

限制输入长度

combobox如果没有选中值

最后


一、窗体转换

转到新窗体

可以关闭或隐藏原窗体

NewForm newForm = new NewForm();
newForm.Show();
this.Close();
//this.Hide();

回到旧窗体

前提是你没有关闭旧的窗体

//在新窗体定义一个字段保存旧窗体
private OldForm old;

// 在新窗体的构造函数中接收对旧窗体的引用
public NewForm(OldForm oldform)
{
    this.old = oldform;
}

// 在新窗体中需要返回旧窗体时
private void ReturnToOldForm()
{
    old.Show(); 
    this.Hide(); 
    //this.Close();
}

当然,这样的话新窗体的构造函数就变了,所以在旧窗体转换到新窗体的时候也需要做一点改变。

NewForm newForm = new NewForm(this);    //把当前所在窗体传参进新窗体
newForm.Show();
this.Close();
//this.Hide();

二、数据库操作·脱机模式

查询一个数据

// 创建SqlConnection对象,连接用windows身份验证的SQL Server数据库  
SqlConnection conn = new SqlConnection("Server = (local); Database = library; Trusted_Connection = yes");  
// 打开与数据库的连接  
conn.Open();  
// 构造SQL查询语句,用于从userInfo表中查找具有指定NickName和Passwords的用户  
string sql = "select count(*) from userInfo where NickName = " + LogName.Text + " and Passwords = " + LogCode;  
// 创建SqlCommand对象,执行SQL查询语句  
SqlCommand comm = new SqlCommand(sql, conn);  
// 执行SQL查询语句,并返回查询结果(也就是用户数量)  
int num = (int)comm.ExecuteScalar();
// 关闭与数据库的连接  
conn.Close();  
// 如果查询结果大于0,说明此用户存在
if (num > 0)  
{  
    // 创建主窗体 
    MainForm mainForm = new MainForm();  
    mainForm.Show();   
    this.Close();  
}  
else  
{  
    // 如果查询结果为0,说明没有找到匹配的用户,显示错误消息框  
    MessageBox.Show("用户名或密码错误,请重新输入或注册新账号", "提示"); 
}

新增或修改数据

//参数化查询避免sql注入风险
comm.CommandText = "insert into recordInfo (UserId, BookId, BorrowDate, Returned) values (@UserId, @BookId, @BorrowDate, 'no')";
comm.Parameters.AddWithValue("@UserId", log.userid); 
comm.Parameters.AddWithValue("@BookId", bookid.Text);
comm.Parameters.AddWithValue("@BorrowDate", DateTime.Now);

查询多个数据

SqlConnection conn = new SqlConnection("Server=(local); Database=library; Trusted_Connection=yes");
conn.Open();
string sql = string.Format("select LTRIM(RTRIM(Admini)),LTRIM(RTRIM(UserId)) from userInfo where NickName = '{0}' and Passwords = '{1}'", LogName.Text, LogCode.Text);
SqlCommand comm = new SqlCommand(sql, conn);
//前面都一样,只是后面不太一样

// 创建一个新的SqlDataAdapter对象,用于执行SQL命令并填充DataTable。  
SqlDataAdapter adapter = new SqlDataAdapter(comm);  
  
// 创建一个新的DataTable对象,用于存储从数据库检索的数据。  
DataTable dt = new DataTable();  
  
// 使用SqlDataAdapter对象填充DataTable。  
adapter.Fill(dt);  
  
// 检查DataTable中是否有行。如果有,则执行下面的代码块。  
if (dt.Rows.Count > 0)  
{  
    // 从第一行第一列获取数据,并将其转换为字符串,然后赋值给变量adm。  
    adm = dt.Rows[0][0].ToString();  
  
    // 从第一行第二列获取数据,并将其转换为字符串,然后赋值给变量userid。  
    userid = dt.Rows[0][1].ToString();  
}

三、限制输入的字符类型

常用函数

char c = (char)Console.Read();
//c是字母?
char.IsLetter(c);       
//c是十进制数字?
char.IsDigit(c);
//c是字母或十进制数字?
char.IsLetterOrDigit(c);

如果是为了密码做限制功能

可以直接把UseSystemPasswordChar属性设置为true,方便省事

四、让tabcontrol的其中一个页面不可见

tabcontrol集合里的tabpage没有visible属性,要想隐藏的话,我试了以下几种方法。

方法一

//让这个page的父容器为空理论上它就不能在tabcontrol显示了
tPageBook.Parent = null;
//想要再显示就把parent属性改回去就行

方法二

//直接把页面删掉
tCtr.TabPages.Remove(tPageBook);

方法三

//隐藏并移除
tCtr.TabPages["tPageBook"].Dispose();

但是由于一些其他的错误,我试了半天也没成功,所以我放弃了,换了个实现这种功能的思路。

比如把界面的入口设置为一个button,只要隐藏button这个页面就也被隐藏了。

最后虽然我发现了那个离谱错误,但是懒得改回去了,所以上述方法是否有效得大家自己尝试了。

五、一点sql语句

查询借书记录,并从图书表格调出书的具体信息,最后把这些东西合成一个表

select  
    -- 选择b.BookId字段,即从子查询中获取图书ID,下面四句差不多 
    b.BookId,    
    b.BookName,    
    b.Genre,  
    b.Author,   
    b.Publisher,   
    
    BorrowDate,  
    ReturnDate,    
    Returned   

-- 创建一个子查询,并命名为subquery_borrow。该子查询从recordInfo表中选取BookId、BorrowDate、ReturnDate和Returned字段。  

from    
    (select BookId, BorrowDate,ReturnDate,Returned from recordInfo) as subquery_borrow 
   
-- 使用JOIN操作将子查询subquery_borrow与bookInfo表连接。连接条件是两个表中的BookId字段相等。  

JOIN    
    bookInfo as b on subquery_borrow.BookId = b.BookId;

六、出现的一些错误

1、System.Data.SqlClient.SqlException:“字符串或二进制数据将在表“library.dbo.userInfo”,列“Passwords”中被截断。截断值:“System.Windows.F”。

这是在执行插入数据的sql语句时出现的,大家都说这是字段长度超过了设置的长度,确实也是这样。

但我寻思我所有输入都有长度限制,怎么会出现这种错误呢,结果是我忘记写“.Text”了。。。

2、comm.ExecuteScalar().ToString()报错

如果 comm.ExecuteScalar()返回 null,直接调用 ToString()方法会导致 NullReferenceException 异常,所以就报错了,可以像我这样改改:

//原代码
string str;
str = comm.ExecuteScalar().ToString();

//改正代码
string str;
object result = comm.ExecuteScalar();
if (result != null)
{
    str = result.ToString();
}

3、查询结果比预期结果多空格,导致判断出错

代码:

//查询正在登录的用户是否是管理员
string sql = string.Format("select Admini from userInfo where NickName = '{0}' and Passwords = '{1}'", LogName.Text, LogCode.Text);
SqlCommand comm = new SqlCommand(sql, conn);
object result = comm.ExecuteScalar();
if (result != null)
{
    adm = result.ToString();
}

如果用户不是管理员,结果应该是"no",但是我最终得到的adm是“no     ”,这就导致了后续许多故障。

解决方案:

//去掉空格
string sql = string.Format("select LTRIM(RTRIM(Admini)) from userInfo where NickName = '{0}' and Passwords = '{1}'", LogName.Text, LogCode.Text);

4、线程间操作无效: 从不是创建控件“pnborr”的线程访问它。

//原代码,在关闭窗体的时候显示另一个窗体
private void BorrowRecord_FormClosed(object sender, FormClosedEventArgs e)
{
    main.Show();
    this.Close();
}

//改好的代码
private void BorrowRecord_FormClosed(object sender, FormClosedEventArgs e)  
{  
    main.Show();
}

这个问题就在于,我已经在调用关闭函数了,但是我又在里面写了this.close(),无限套娃了。

5、System.Data.SqlClient.SqlException:“变量名 '@UserId' 已声明。

/*这是报错的代码,写在一个函数里,但是由于我的comm是全局变量,
所以第二次调用的时候就会报错说变量已声明*/
comm.Parameters.AddWithValue("@UserId", log.userid); 
comm.Parameters.AddWithValue("@BookId", bookid.Text);
comm.Parameters.AddWithValue("@BorrowDate", DateTime.Now);

//只要在代码前面加上下面这句就可以解决了
comm.Parameters.Clear();
//也就是在每次声明变量前把已有的变量都清除

6、datagridview更新失败

错误代码:

string sele = bookcb.SelectedItem.ToString().Substring(1,2);
string found = booktb.Text;

//创建新表储存数据
DataTable bookdt1 = new DataTable();

//bookdt是我本来的数据源
foreach (DataRow row in bookdt.Rows)
{
    if (row[sele].ToString().Trim() == found)
    {
        bookdt1.ImportRow(row);
    }
}
if (bookdt1.Rows.Count > 0)
{
    dgviewbook.DataSource = bookdt1;
    dgviewbook.Refresh();
}

错误原因应该是我这个新表只有行数据,但是没有列结构,所以我选择在填充bookdt的时候填出一个一模一样的bookdt1。

更正后代码:

//填充数据
SqlDataAdapter adapter = new SqlDataAdapter(comm);
adapter.Fill(bookdt);
adapter.Fill(bookdt1);

//新代码
string sele = bookcb.SelectedItem.ToString().Substring(1,2);
string found = booktb.Text;
bookdt1.Rows.Clear();
foreach (DataRow row in bookdt.Rows)
{
    if (row[sele].ToString().Trim() == found)
    {
        bookdt1.ImportRow(row);
    }
}
if (bookdt1.Rows.Count > 0)
{
    dgviewbook.DataSource = bookdt1;
    dgviewbook.Refresh();
}

七、杂记(大部分是属性)

1、给label里的文字加下划线

属性font里

2、限制输入长度

MaxLength属性

3、combobox如果没有选中值

  1. ComboBox的SelectedIndex属性值为-1,表示未选中任何项。
  2. ComboBox的SelectedItem属性值为null。
  3. ComboBox的SelectedValue属性值为null。

4、datagridview的字体格式

列标题字体格式在ColumnHeadersDefaultCellStyle属性

单元格字体格式在DefaultCellStyle属性

5、把某些控件设置为半透明

//前面三个数值分别是红绿蓝色值
gbSetBook.BackColor = Color.FromArgb(168, 245, 243, 220);
//最后一个数220代表透明度,范围从完全透明(0)到完全不透明(255)

最后

ai还是挺好用的,至少写注释非常清晰,我浅改一下就可以了,妈妈再也不用担心我以后看不懂自己的代码啦。

这篇笔记是边写实验边记的,有什么记什么,所以很凌乱,写完实验如果我有时间可能会再重写一篇。

  • 7
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值