这几天弄一个题库的项目,语言用的是c#,但是我对c#又不是很熟悉,特别是里面的一些控件的一些细节问题,而微软的东西有不怎么开源,想弄清楚又难,所以有时候一个问题,可能都要好久才能弄出来,以下呢,是我这几天遇到的问题,以及解决的方案,希望能让在遇到我遇到的问题时,能不在花很久时间```
1. 文本输入中,需要放图片,文字,表格``等,存放到数据库的问题?
第一步: 不要用textBox,用richTextBox控件(这样它就允许图片,表格等的输入)
第二步: 数据库中的字段用varbinary(Max)(如果是image,可能存在某些图片类型的前70个字节是存的文件格式,有时候定位就得从70开始了)
第三步: 写两个转换函数(分别是输入文本转换成byte[]存到数据库中 ,和 byte[]转换成到richtextBox中显示的文本)(这里是针对richtextbox,其他的控件可能不同)
//把二进制流装换成文字图片
private void ImageChangeToRText(RichTextBox rtBox, byte[] Content)
{
//下面是读取
byte[] b = Content;
MemoryStream ms = new MemoryStream();
ms.Position = 0;
ms.Write(b, 0, b.Length);
ms.Position = 0;
rtBox.LoadFile(ms, RichTextBoxStreamType.RichText);
ms.Close();
}
//把文字图片装换成二进制流(并当成返回值返回)
private byte[] RTextChangeToImage(RichTextBox rtBox)
{
//建立内存流
MemoryStream ms = new MemoryStream();
ms.Position = 0;
//把当前的richtextbox内容包括图片和文本保存到流中
rtBox.SaveFile(ms, RichTextBoxStreamType.RichText);
//得到byte数组并写入值
byte[] biStr = new byte[(int)ms.Length];
ms.Position = 0;
ms.Read(biStr, 0, biStr.Length);//这个的biStr就可以直接写入数据库中了,
ms.Close();
return biStr;
}
第四步: 分别在使用的时候调用就可以了
2. 储存过程嵌事务的创建与使用(下面给出一个实例.没有讲解)
--创建一个插入题目的储存过程
create proc proc_insertQuestion(
@eQuestionID char(6)output,--返回值(题目编号)
@knowledgeID_Subject char(8),
@qTypeID char(5),
@eQOrder char(4) output,--返回值(顺序码)
@eQContent image,
@eQAnswer image,
)
AS
BEGIN
begin tran --事务处理开始
declare @Order varchar(4)
--查找记录值
set @Order = (select convert(varchar(4),MAX(eQOrder)+1) from EQuestion where SubString(eQuestionID,1,2)=(SubString(@knowledgeID_Subject,1,2)))
--根据Order的长度来给eQOrder赋值
if (LEN(@Order) = 1)
set @eQOrder = ('000'+@Order);
else if(LEN(@Order) = 2)
set @eQOrder = ('00'+@Order);
else if(LEN(@Order) = 3)
set @eQOrder = ('0'+@Order);
else
set @eQOrder = (@Order);
--插入记录值
INSERT INTO EQuestion
(knowledgeID_Subject,qTypeID,eQOrder,eQContent,eQAnswer,
)
VALUES
(@knowledgeID_Subject,@qTypeID,@eQOrder, @eQContent,@eQAnswer
)
--事务结果处理
if(@@error=0) --如果事务顺利完成没有异常
begin
commit tran --事务完成
return 1;
end
else
begin
rollback tran --事务回滚
return -1;
end
END
3. DataGridView绑定数据集中某一张表的DataView,点击DataGridView时把记录显示到一些控件中,然后当修改了这些控件中的值的时候,点击提交就希望修改到DataGridView里面,而且希望更新到本地数据集DataSet中(本地数据集是否更新可以通过DataSet.hasChange()函数来检测,为true表示更新了).然后在通过DataSet更新到数据库中去.
方法思路:在绑定DataView的时候,不直接绑定DataView,而通过绑定BindingSource,在把DataGridView绑定到BindingSorece,然后这时候当你直接对DataGridView修改了后,才会更新到本地数据集DataSet中,具体如下:
第一步: 定义一个全局变量 BindingSource mainBindingSource; //绑定源
第二步: 在绑定的时候,不直接绑定DataView,而是绑定BindingSource
DataView mainDataView;
mainDataView = mainDataSet.Tables["TableName"].DefaultView;
string sqlstr = "";//这里可以通过控制sqlstr来控制DataView中的数据集合
mainDataView.RowFilter = sqlstr;//筛选语句
mainBindingSource = new BindingSource(); //这里的mainBindingSource的全局定义的,因为要在后面修改的时后用到
mainBindingSource.DataSource = mainDataView;
dGView_QF_QuestionDisplay.DataSource = mainBindingSource; //关键,不能直接绑定DataView,而是通过BindingSource
第三步: 修改DataGridView,并使得本地数据集也能修改(可以定义一个函数来更新)
private void UpdateQuestionToDS()
{
//选中次数
dataGridView.CurrentRow.Cells["columnName1"].Value = "想修改的内容";
//题目提供者
dataGridView.CurrentRow.Cells["columnName2"].Value ="想修改的内容";
mainBindingSource.EndEdit();//关键点 结束数据源的编辑,使得mainDataSet能更新我所编辑后的内容
}
(PS: 第三个问题,别看简单,还可以解决下面的问题:)
C#,Form程序,把dataset数据绑定到datagridview,datagridview中的数据更改后点击保存按钮,利用dataset.HasChanges(),来判断是否有数据更新。
但是有这么个细节:我改了其中1行数据,不更改选中行的情况(即鼠标不去点击dgv中的其它行)直接点保存,dataset.HasChanges()没反应,只有我先点击一下datagridview中的其它行,再点击保存,dataset.HasChanges()才有反应。可以通过上面的方法去掉多余的点击步骤.