S R B 项目总结

时间:2022-10-27 13:37:48

S R B 项目总结
S R B 项目总结 

一:设计方面

1Label的慎用:Label被打到前台的时候,显示的是span,随之而来也会带来问题。首先:代码的encodedecode。其次:如果Label放在表格的一个td里面,如果Label过长,导致被td覆盖,看不到后面的,也不能拖动使之显示。还有:如果Label用来展现从数据库中读出的数据时,如果数据库此字段前面有多个空格。因为Html不对空格进行解析,所以导致视觉上空格不能被展示出来。

解决方案:用TextBox代替Label用于数据展示。TextBox不需要考虑encodedecode问题。其他2个问题也可以被解决。TextBox可以用css样式使之看上去和Label具有相同的外观。

.txtLabelLike
{

    border-top: 1px solid #FFFFFF;

    border-left: 2px solid #FFFFFF;

    border-right: 2px solid #FFFFFF;

    border-bottom: 1px solid #FFFFFF;

}

2:多行文本框的问题

  <asp:TextBox CssClass="txtEnabled" Rows="4" TextMode="MultiLine" Columns="92" MaxLength="255"></asp:TextBox>

一些备注一类的使用多行文本框。多行文本框的使用需要注意以下问题:

l          多行文本框的MaxLength虽然可以设置,但是却不起作用。

l          虽然多行文本框也可以设置heightwidth属性,但是推荐使用CloumnsRows属性代替之。需要注意的是Rows属性设置的行高是以阿拉伯数字和英文字母为参考,所以在上面的例子中如果填写4行汉字,最后一行文字的底部会有部分被覆盖住。

l          多行文本框每次回传提交的时候,前面和后面的回车换行符会被各“吃掉”一个。现在还没有找到什么好的解决方案,推荐的解决方案是;如果没有特殊的要求,可以trim掉多行文本框的空格和换行符。支持看上去不会那么“奇怪”。

 

3:服务器端和客户端

应该尽量避免对同一业务过程同时使用客户端控制和服务器端控制。这样的设计会比较容易出现错误。如果一定要使用客户端和服务器端的同时控制需要注意以下问题:

l          一些类似下拉列表框的控件,如果是必须是服务器端控件,则对其的onchange事件需要用脚本来控制以避免页面的刷新让客户无法接受。

l          如果对一个控件,同时进行用脚本来清空和服务器端的清空(修改),需要注意的是:用脚本虽然清空(修改)了,但是只是客户端的清空(修改),这时候,此控件的服务器端的数值并没有被清空(修改),一回传,客户端的值又会被服务器端的值覆盖。

 

二:编码方面

1:每一个文本框都应该设置widthmaxLength,如果没有设置,重点确认一下。

2:对于用户输入的内容注意是否需要以下的处理:

l          Trim 或者 TrimEnd

l          大写转换为小写

l          全角转换为半角

    txtProjectNO.Text = Utility.ToHanKaku(txtProjectNO.Text).ToUpper

l          如果输入的是日期,请参考下面的函数处理之


对日期的验证

Public Shared Function ValidateYMD(ByVal p_strValidatedYM As String) As Boolean

     Try

     转为半角后TrimEnd

         p_strValidatedYM = Utility.ToHanKaku(p_strValidatedYM).TrimEnd

     利用正则表达式验证日期格式

         If Regex.IsMatch(p_strValidatedYM, "\d{4}\D\d{1,2}\D\d{1,2}") Then

     判断最大日期和最小日期范围

             If Not Check.IsDate(p_strValidatedYM) OrElse _

                CDate(p_strValidatedYM) > CDate(CommonConst.MAX_YMD) OrElse _

                CDate(p_strValidatedYM) < CDate(CommonConst.MIN_YMD) _

             Then

                 Return False

             End If

         ElseIf p_strValidatedYM <> String.Empty Then

             Return False

         End If

         Return True

     Catch ex As Exception

         Return False

     End Try

End Function

 

转换为半角文字

Public Shared Function ToHanKaku(ByVal p_strText As String) As String

     If p_strText Is Nothing Then

         Return String.Empty

     End If

     Return StrConv(p_strText, VbStrConv.Narrow)

End Function

 

转换为日期格式

Public Shared Function IsDate(ByVal p_strText As String) As Boolean

    Try

        Date.Parse(p_strText)

        Return True

    Catch

        Return False

   End Try

End Function

 

l          如果要输入的是数量等数值,请参考下面的过程处理之

对数量的验证(用户自定义控件)

Protected Sub ValidateAmountData(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs)

    Dim l_strNumber As String

    Try

        args.IsValid = False

        要去掉逗号,还要转为半角,不能让全角通过

        l_strNumber = Utility.ToHanKaku(Utility.RemoveComma(args.Value))

       If Not Check.StringInLength(CDec(strNumber)).ToString("##0"), 10) Then

          Exit Sub

       End If

        If Not Check.IsNumeric(l_strNumber) Then

            Exit Sub

        End If

        If CDec(l_strNumber) < 1 Then

            Exit Sub

        End If

        args.IsValid = True

    Catch ex As Exception

        args.IsValid = False

    End Try

End Sub

 

去掉逗号的函数

Public Shared Function RemoveComma(ByVal p_strText As String) As String

    Return p_strText.Replace(",", String.Empty).Replace("", String.Empty)

End Function

 

判断是非为数值的函数

Public Shared Function IsNumeric(ByVal p_strText As String) As Boolean

    Try

        Double.Parse(p_strText)

        Return True

    Catch

        Return False

    End Try

End Function

 

判断字符串长度是否合法的函数

Public Shared Function StringInLength(ByVal p_strText As String, ByVal p_intLength As Integer) As Boolean

    If p_intLength < GetEncoding.GetByteCount(p_strText) Then

        Return False

    End If

    Return True

End Function

 

取得文字的编码规则

Public Shared Function GetEncoding() As Encoding

    Try

        Return Encoding.GetEncoding("shift-jis")

    Catch

        Return Encoding.Default

    End Try

End Function

l          如果输入的是金额等数值,请参考下面的过程处理之

单价的验证处理过程例子(用户自定义控件)

Protected Sub ValidateUnitPriceData(ByVal source As Object, ByVal args As System.Web.UI.WebControls.ServerValidateEventArgs)

Dim l_strNumber As String

Try

    args.IsValid = False

    If args.Value = String.Empty Then

        Exit Sub

    End If

    l_strNumber = Utility.ToHanKaku(Utility.RemoveComma(args.Value))

    If Not Check.IsNumeric(l_strNumber) Then

        Exit Sub

    End If

    If CDec(l_strNumber) < 0 Then

        Exit Sub

    End If

    If CDec(l_strNumber) <> CDec(Utility.FormatMoney(l_strNumber)) Then

        Exit Sub

    End If

    args.IsValid = True

Catch ex As Exception

    args.IsValid = False

End Try

End Sub

 

格式化金额

Public Shared Function FormatMoney(ByVal p_strText As String) As String

    If Check.IsNumeric(p_strText) Then

        Return CDec(p_strText).ToString("###,##0")

    End If

    Return p_strText

End Function

 

3:对于从数据库中读取出来展现在页面上的内容注意是否需要以下的处理:

l          如果是用Label展现出来的一定要注意encode,防止形如<input>这样的数据。

l          如果数据库中的数据,前面包含很多的空格,如果用Label展现的话,空格不会被表现出来(虽然查看html的时候,空格是存在的。)

l          是否需要Trim或者TrimEnd

l          应该考虑数据库中此字段是否有可能为DBNull。如果可能要使用下面的方法处理之

'申請依頼元社員氏名

ucStaff.StaffName = Utility.GetFieldOfString(.Item(ConstData.ViewConst.V_STAFF_INFO.STAFF_NAME)).TrimEnd

 

GetFieldOfString函数

Public Shared Function GetFieldOfString(ByVal p_objDBdata As Object) As String

    Return GetFieldOfString(p_objDBdata, String.Empty)

End Function

 

GetFieldOfString函数,重载

Public Shared Function GetFieldOfString(ByVal p_objDBdata As Object, ByVal p_strDefaultValue As String) As String

    If p_objDBdata Is DBNull.Value Then

        Return p_strDefaultValue

    Else

        Return CStr(p_objDBdata)

    End If

End Function

 

4:用户控件可以通过如下的方法找到包含此用户控件页面上的其他控件

ViewState(ConstData.ViewState.SRBU9001_DEPTCODE_LABEL_ID)为一开始传进来的父页面上的某个LabelID

DirectCast(Me.Parent.FindControl(ViewState(ConstData.ViewState.SRBU9001_DEPTCODE_LABEL_ID).ToString), Label).Text = Txt

 

5:文本框的onchange事件

文本框的onchange事件并不像看上去那么简单,这是个令人头痛的问题。因为文本框本身的onchange事件存在一些bug,有一定几率不触发。(例如在打开拼音输入法是,没有按回车确定输入法中显示的文字是直接离开文本框就有一定几率使得onchange事件不触发。)所以我们使用了onfocusin,记下当时数值,在onfocusout时对比与onfocusin时的数值模拟onchange事件。但是此种方法也会有问题。就是在用户用鼠标拖拽数据使内容发生变化时,onfocusin事件不会被触发。

最终的解决方案如下:

首先:在js脚本文件中添加下面语句,禁用此页面的拖拽功能

document.attachEvent("ondragstart",function(){return false;})

 

然后在共同的文件里面添加以下共同的过程

AddTextBoxValueChangeEvent通用部分

Public Shared Sub AddTextBoxValueChangeEvent(ByVal p_objTextBox As TextBox)

    Dim l_objFocusout As New StringBuilder

    l_objFocusout.Append("if (this.savevalue == this.value) return;")

    l_objFocusout.AppendFormat("if (typeof({0}) == 'function') {0}();", p_objTextBox.ClientID & "_onvaluechange")

    l_objFocusout.Append("this.savevalue = this.value;")

   

    p_objTextBox.Attributes.Add("savevalue", "")

    ’获得焦点的时候用savavalue(自己定义的属性)记录当前值

    p_objTextBox.Attributes.Add("onfocusin", "this.savevalue = this.value;")

    失去焦点时,触发在前台自己定义的onchange事件

    p_objTextBox.Attributes.Add("onfocusout", l_objFocusout.ToString)

    拖拽进来时触发获得焦点事件

    p_objTextBox.Attributes.Add("ondragenter", "this.focus();")

    禁止在文本框上进行拖拽

    p_objTextBox.Attributes.Add("ondragstart", "return false;")

End Sub

 

然后在后台对需要添加onchange事件的文本框添加以下代码

txtProjectNO添加onchange事件

ClientAPI.AddTextBoxValueChangeEvent(txtProjectNO)

 

最后在前台或者后台添加相如function <%=txtProjectNo.ClientID%>_onvaluechange()js脚本函数

在前台写法如下:


 

   function <%=txtProjectNo.ClientID%>_onvaluechange()

   {

        document.all.<%=lblProjectName.ClientID%>.innerText="";

        document.all.<%=txtProjectValidFlag.ClientID%>.value="0";         

   }

在后台写法如下:

Dim l_objScript As New System.Text.StringBuilder

 

With l_objScript

    .AppendLine("function " & txtProjectNo.ClientID & "_onvaluechange()")

    .AppendLine("{ ")

    .AppendLine("document.getElementById(""" & lblProjectName.ClientID & """). innerText ="""";")

    .AppendLine("document.getElementById(""" & txtProjectValidFlag.ClientID & """).value=""0"";")

    .AppendLine("}")

End With

 

注册脚本

Me.Page.ClientScript.RegisterClientScriptBlock(Me.Page.GetType(), Me.ID & "ProjectNoOnchange", l_objScript.ToString(), True)

6多个控件执行同一个过程

按钮

AddHandler btnRegisterCancel.Click, AddressOf RegisterCancel

验证控件

AddHandler cuvHopeDeliverDateNoteIncludeHanaComma.ServerValidate, AddressOf ValidateIncludeHanaComma

 

7取得系统日付的方法

'申請日=システム日付

lblApplyDate.Text = CStr(DateTime.Today())

 

8如果同一个控件有多个验证控件对其进行验证,可以将多个验证控件的显示都设置为动态,这样就无须自己去考虑验证控件的星号显示时的间隔问题。文本框和多个验证控件,多个文本框之间的Html代码不能有空格和回车。

<asp:TextBox ID="txtApplicantNote" runat="server" ></asp:TextBox><asp:CustomValidator ID="cuvApplicantNoteIncludeComma" Enabled="false" runat="server" EnableClientScript="false"                            ControlToValidate="txtApplicantNote" Text="*" Display="Dynamic"></asp:CustomValidator><asp:CustomValidator ID="cuvApplicantNote" Enabled="false" runat="server" EnableClientScript="false"                            ControlToValidate="txtApplicantNote" Text="*" Display="Dynamic"></asp:CustomValidator>

 

9多行文本框在预览的时候可能不能显示完整,可以在预览的时候利用下面的样式,使之出现竖向滚动条。

.txtPreview

{

    overflow-y: auto;

}