一、遇到的问题:
关于SQL中的cast、convert函数
解决方法:
CAST ( expression AS data_type )
例:cast(cast(ONLineQty*100/(select sum(ONLineQty) from @tablevar) as decimal(10,2)) as varchar) +'%'
CONVERT (data_type[(length)], expression [, style])
例:SELECT CONVERT(varchar(10),getdate(),121) now 得:2005-12-31
SELECT CONVERT(varchar(10),getdate(),101) now 得:12/31/2005
关于“style”参数取值的意义详细可参见联机丛书。
(当然,取varchar长度为10是限制日期型只显示到日期,这是比较常用的。例如,当datagrid控件中绑定数据列时,通常只要求显示到day即可,可以采用上述方法,也可用datagrid的DataFormatString="{0:yyyy-MM-dd}"来限制。)
二、遇到的问题:
关于datagrid中的绑定列的DataFormatString属性
解决方法:
用DataFormatString="{0:yyyy-mm-dd}"来规范日期显示时出现错误,月份无法正确显示,仔细检查才发现是将数据库日期中的分钟读到了mm位置,应写作:DataFormatString="{0:yyyy-MM-dd}"才正确,^^。
三、遇到的问题:
关于正则表达式的一些细节
解决方法:
(1)方括号符号
你可以在方括号(“[]”)里面指定匹配的字符。此时,只有方括号里面指定的字符才参与匹配。也就是说,正则表达式“t[aeio]n”只匹配“tan”、“Ten”、“tin”和“ton”。但“Toon”不匹配,因为在方括号之内你只能匹配单个字符。可以其后应用?、+和*等符号。
(2)圆括号符号
如果除了上面匹配的所有单词之外,你还想要匹配“toon”,那么,你可以使用“|”操作符。“|”操作符的基本意义就是“或”运算。要匹配“toon”,使用“t(a|e|i|o|oo)n”正则表达式。这里不能使用方扩号,因为方括号只允许匹配单个字符;这里必须使用圆括号“()”。圆括号还可以用来分组,将字符组合起来作为一个整体以便应用?、+和*等符号。例如ba(na)+na//匹配"banana"和"banananana"
四、遇到的问题:
关于受VSS管理的源代码
解决方法:
从别处复制来一个项目,原项目原来受VSS管理,复制到本地后打开出现错误,把项目文件中有关VSS的文件悉数删除,注意几乎所有的文件夹下都有VSS文件,另外将文件夹及所有子文件夹和文件的属性中的“只读”除去,好像没问题了。(不知道正确的方法是怎么做)
五、遇到的问题:
关于DataGrid中的模板列
解决方法:
在模板列中添加CheckBox,选中后点击按钮删除的代码示例:
private void btDel_Click(object sender, System.EventArgs e)
{
CheckBox cb;
int ID;
bool sign=false;
//循环判断,删除选中列
foreach(DataGridItem dgi in this.DataGrid1.Items)
{
cb=(CheckBox)dgi.FindControl("cbSelect");
if(cb!=null && cb.Checked ==true)
{
sign=true;
ID=int.Parse(dgi.Cells[1].Text.Trim());
try
{
IMachineRelation iMR=new Entity.MachineRelation();
iMR.DelMachineRelation(ID);
}
catch(Exception ex)
{
this.lbError.Text =ex.Message;
}
}
}
//用户未作选择时给出提示
if(sign==false)
{
this.lbError.Text ="......"
return;
}
BindData();
}
六、遇到的问题:
关于DataGrid中的超链接列
解决方法:
在属性生成器中,通常可指定超链接列的:
“文本”属性,即用于显示的文字;
“文本字段”,即指所显示的将是根据结果集中的数据动态生成的文字;
“URL字段”,通常用于传递参数时使用到,见下一属性,只有指定属性才能“URL格式字符串”属性才变为可用;
“URL格式字符串”,通常写作类似“FrmMachineRelation_Modify.aspx?FID={0}”这样,而传递的参数即为数据集中“URL字段”指定的字段的值。而0并非列的索引值。
七、遇到的问题:
关于DataGrid的ItemDataBound事件等
解决方法:
每当一条数据被绑定到DataGrid上时,该事件被触发。即只要执行了DataBind,就会马上激发这个事件。
当数据只有9行时,下面itemdatabound事件会输出11行,因为包含页“页眉”、“页脚”:
private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
this.TextBox1.Text +="itemdatabound..."+e.Item.ToString()+Environment.NewLine;
}
以下代码则输出9行:(ListItemType类型中包括:item-项;AlternatingItem-交替项;footer;header;pager)
private void DataGrid1_ItemDataBound(object sender, System.Web.UI.WebControls.DataGridItemEventArgs e)
{
if(e.Item.ItemType ==ListItemType.Item || e.Item.ItemType ==ListItemType.AlternatingItem)
{
this.TextBox1.Text +="itemdatabound..."+e.Item.ToString()+Environment.NewLine;
}
}
另外:
我们写程序的时候,一般都会有这个
Page_Load
if(!Page.IsPostBack)
{
DataGrid1.DataSouce = ..........;
DataGrid1.DataBind();
}
如果页面是第一次访问(Page.IsPostBack = false),那在第一次执行DataBind的时候,会先激发ItemCreated事件,也就是说,执行了DataBind后,首先会用ItemCreated来建立Header行,然后用ItemDataBound来绑定Header行,再用ItemCreated来建立第一行,再调用ItemDataBound来绑定第一行,也就是说ItemCreated和ItemDataBound是交替执行的。
页面PostBack时,也会执行ItemCreated事件,这个方法是不受IsPostBack的限制的,但是这时候就不会再执行ItemDataBound事件了。
八、遇到的问题:
如何使DataGrid中出现一个空行
解决办法:
以下代码可以使datagrid出现一个空行
da.Fill(ds,"emp");
string[] sArray=new string[ds.Tables["emp"].Columns.Count];
ds.Tables["emp"].Rows.Add(sArray);
this.DataGrid1.DataSource =ds;
this.DataGrid1.DataBind();
或者可类似第十点中所示的方法。
九、遇到的问题:
关于DataGrid中合并行及其preRender事件
解决方法:
控件的preRender事件用于:在服务器控件呈现给页的输出之前执行任何更新。即对呈现形式进行修改。
在DataGrid中,有时会遇到如下的问题:将
中国 |
上海 |
电脑 |
中国 |
上海 |
数码相机 |
中国 |
上海 |
数码相机 |
中国 |
北京 |
数码相机 |
中国 |
北京 |
电脑 |
中国 |
北京 |
电脑 |
中国 |
上海 |
电脑 |
数码相机 |
||
北京 |
数码相机 |
|
电脑 |
即进行合并行操作,此时可用到DataGrid的preRender事件:
private
void DataGrid2_PreRender(object sender, System.EventArgs e)
{
JoinCells.Jion(this.DataGrid2,2);
}
JoinCells类:
public class JoinCells
{
public JoinCells()
{ }
/// <summary>
/// 合并DataGrid中相同内容的行
/// </summary>
/// <param name="objDG">所要操作的DataGrid</param>
/// <param name="index">指出对第0列到第index列,每列中相同内容的行进行合并</param>
public static void Jion(DataGrid objDG,int index)
{
for(int i=0;i<=index;i++)
{
TableCell tcNow=objDG.Items[0].Cells[i];
for(int j=1;j<objDG.Items.Count;j++)
{
TableCell tcNext=objDG.Items[j].Cells[i];
if(tcNext.Text.Trim()==tcNow.Text.Trim()&&CheckPre(objDG,j,i))
{
tcNext.Visible =false;
if(tcNow.RowSpan ==0)
{
tcNow.RowSpan =1;
}
tcNow.RowSpan +=1;
tcNow.VerticalAlign =VerticalAlign.Middle;
}
else
{
tcNow=tcNext;
}
}
}
}
//做简单的向前检查,看所要合并的两行是否属同一系列,
//(避免将上海的数码相机与北京的数码相机合并)
private static bool CheckPre(DataGrid objDG,int rowIndex,int colIndex)
{
if(colIndex==0)
{
return true;
}
Else if(objDG.Items[rowIndex-1].Cells[colIndex-1].Text.Trim()==objDG.Items[rowIndex].Cells[colIndex-1].Text.Trim())
{
return true;
}
else
{
return false;
}
}
}
十、遇到的问题:
关于DataGrid中实现跨行表头
解决方法:
在DataGrid中有时需要实现类似如下形式:
A |
B |
|
B1 |
B2 |
|
|
|
|
首先,为DataTable添加一个空行:
objDS=new DataSet();
objDS=DataAccess.ExecProc(procName);
//添加空DataRow,并排序
DataTable dt=objDS.Tables[0];
DataRow dr=dt.NewRow();
dt.Rows.Add(dr);
DataView myDataView = dt.DefaultView;
myDataView.Sort = "AreaName ASC";
this.dgDeposit.DataSource =dt;
this.dgDeposit.DataBind();
接着,对表头进行处理:
Private void dgDeposit_ItemDataBound(object sender,DataGridItemEventArgs e)
{
flag++;
if(flag==1)//处理原表头
{
for(int i=0;i<=4;i++)
{
e.Item.Cells[i].RowSpan =2;
}
e.Item.Cells[5].ColumnSpan =2;
e.Item.Cells[5].Text =title;
e.Item.Cells[5].HorizontalAlign =HorizontalAlign.Center;
//由于某些单元格占用了多列多行,会将原有的单元格向右挤,须删去
for(int i=0;i<1;i++)
{
e.Item.Cells.RemoveAt(6);
}
}
else if(flag==2)//处理新插入的空行,以作多行表头
{
for(int i=0;i<2;i++)
{
e.Item.Cells[i].Text =sArray[i];
e.Item.Cells[i].Width =Unit.Pixel(50);
e.Item.Cells[i].BackColor =Color.RoyalBlue;
}
//由于某些单元格占用了多列多行,会将原有的单元格向右挤,须删去
for(int i=0;i<5;i++)
{
e.Item.Cells.RemoveAt(2);
}
}
}
(程序中是稍微复杂的一种情况,和表格所画并不完全相同)