程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> ActiveReports工作總結11——麻煩的線線框框

ActiveReports工作總結11——麻煩的線線框框

編輯:.NET實例教程

在我使用AR的過程當中,碰到最大的困難,不是數據的組織(雖然也很麻煩),而是畫面的布局,尤其是一些奇怪的線線框框,常常會為了一些特殊的線框要求,浪費很多時間調試。

本節我就把在項目的碰到的一些常見框線問題,簡單的進行一下分析。

 

1,帳票式樣,還是上節那張帳票。

該帳票的框線要求是:3個sub模版的四周要求粗線;Detail中的紀錄,要求每5行為粗線。

2,對於一個textbox或label等控件,初始狀態是沒有邊框的(就像圖中的”成績一覽表”這個控件),為控件提供邊框,一般有2種方法。

    1)給控件設置border(right click控件,選border),這樣可以很方便的給控件設置4條邊框。

    當然,也可以代碼中控制:


        ''Set four borders.

        Me.TextBox3.Border.Style = BorderLineStyle.Solid

        ''Set the top border.

        Me.TextBox3.Border.TopStyle = BorderLineStyle.Solid

 

    style可以設置成虛線,實線等。粗細有普通,2倍,4倍像素(僅適用於實線)

    2)給控件四周手動畫4條line。

       你可以直接在rpt畫面上畫上4條線,然後在界面或代碼中控制他們的位置。

              當然,你也可以在代碼中直接動態生成4條line

 

       方法1)的好處是方便,而且一樣可以在代碼中做控制(比如加粗top line,隱藏right line等);但同時也有一點局限性比如框線的粗細設定不夠靈活(只能1,2,4倍),對於有嚴格規定的帳票,並不適用,而且當控件比較多的話,給每個控件設置border也是挺麻煩的。

       方法2)的好處是很靈活,同時可以寫個共通方法,對整個section內的控件一次性畫線。缺點是稍微麻煩了點。

用哪種方法可以根據實際情況,圖中,右上角的教師承認欄肯定是用方法1)簡單,而下面數據區域一般用方法2),這樣比較容易控制框線。

 

3先確定一些概念。

       1)整個rpt上,不管是section、控件的位置,高寬,還是實際打印的printWidth都是用Inch(英寸)為單位;

       而line的weight和控件border的粗細,確是以pixels為單位的

       2)不管是畫線,還是直接調整控件的border,框線的粗細都是以中點為基點,向2邊擴張或縮小的,如圖:

<!--[if !vml]-->
<!--[endif]-->

       這樣就會產生一個問題,如圖:

<!--[if !vml]-->
<!--[endif]-->

用的是方法1),由於border向2邊擴張,所以產生了字和框線重疊的問題。這在控件比較小,而框線特別粗的情況下會發生。

為了解決這個問題,我們有一種偏移控件的方法:

用方法2),把線畫在控件的外面,比如要在控件top上畫一條4單位寬的線,則就在控件上2單位高度的地方畫線,這條線會向上和向下各擴張2單位,這樣,線的下部正好和控件的頂部碰到,而又不會發生重疊的現象。當然,用這種方法的話,需要控制好控件之間的間距,否則2個控件之間的框線會互相重疊。

 

恩,我在這裡僅僅提供一個思路,具體怎麼做自己可以實踐一下。我下面的示例沒有用這種偏移控件的方法,只是簡單的在控件上畫線而已。

4,改造example10,改成方法2)畫線(直接在控件上畫線了,沒有去設置控件的偏移)

先把sub1,sub2,sub3上面控件的border都去掉,然後再代碼中動態生成line(示例代碼為sub1.vb)


    Private secGroupHeader1 As SectionLines

    Private secGroupHeader2 As SectionLines

    Private secDetail As SectionLines

 

    Public Structure SectionLines

       &nbsp;Public TopLine As Line

        Public BottomLine As Line

        Public LeftLine As Line

        Public RightLine As Line

    End Structure

 

    Private Sub sub1_ReportStart(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ReportStart

 

        ''

        ''

 

        Me.secGroupHeader1 = Me.DrawLine(Me.GroupHeader1, New ARControl() {Me.lbl1})

        Me.secGroupHeader2 = Me.DrawLine(Me.GroupHeader1, New ARControl() {Me.lblID, Me.lblName})

 

        Me.DrawLine(Me.Detail, New ARControl() {Me.txtID, Me.txtName})

 

        ''

        ''

End Sub

 

    '''''' <summary>

    '''''' 對一排控件進行集體畫綫,不在同一排上的控件,不能一起畫

    '''''' </summary>

    '''''' <param name="section">The section.</param>

    '''''' <param name="controls">The controls.</param>

    '''''' <param name="outlineBorderWeight">外框的粗細.</param>

    '''''' <param name="inlineBorderWeight">內框的粗細.</param>

    '''''' <returns></returns>

    '''''' <remarks></remarks>

    Private Function DrawLine(ByVal section As Section, ByVal outlineBorderWeight As Single, ByVal inlineBorderWeight As Single, ByVal controls As ARControl()) As SectionLines

        If controls Is Nothing OrElse controls.Length = 0 Then

            Return Nothing

        End If

 

        Dim sec As New SectionLines

        Dim ln As Line

 

        Dim controlsNum As Int32 = controls.Length

        ''畫第一個控件到倒數第2個控件的右綫

        For iForControls As Int32 = 0 To controlsNum - 2

            ''Right line

            ln = New Line

            ln.LineWeight = inlineBorderWeight

            ln.BringToFront()

            section.Controls.Add(ln)

            With ln

                .X1 = controls(iForControls).Left + controls(iForControls).Width

                .Y1 = controls(iForControls).Top

                .X2 = .X1

                .Y2 = controls(iForControls).Top + controls(iForControls).Height

            End With

        Next

 

        ''畫所有控件的top綫

        ''Top line

        ln = New Line

        ln.LineWeight = outlineBorderWeight

        ln.BringToFront()

        section.Controls.Add(ln)

        With ln

          &nbsp; ''x1和x2要増加偏移量

            .X1 = controls(0).Left - 0.007F * outlineBorderWeight / 2

            .Y1 = controls(0).Top

            .X2 = controls(controlsNum - 1).Left + controls(controlsNum - 1).Width + 0.007F * outlineBorderWeight / 2

            .Y2 = .Y1

        End With

        sec.TopLine = ln

 

        ''畫所有控件的bottom綫

        ln = New Line

        ln.LineWeight = outlineBorderWeight

        ln.BringToFront()

        section.Controls.Add(ln)

        With ln

            ''x1和x2要増加偏移量

            .X1 = controls(0).Left - 0.007F * outlineBorderWeight / 2

            .Y1 = controls(0).Top + controls(0).Height

            .X2 = controls(controlsNum - 1).Left + controls(controlsNum - 1).Width + 0.007F * outlineBorderWeight / 2

            .Y2 = .Y1

        End With

        sec.BottomLine = ln

 

        ''畫最左面的left綫

        ''Left line

        ln = New Line

        ln.LineWeight = outlineBorderWeight

        ln.BringToFront()

        section.Controls.Add(ln)

        With ln

            .X1 = controls(0).Left

            .Y1 = controls(0).Top - 0.007F * outlineBorderWeight / 2

            .X2 = .X1

            .Y2 = controls(0).Top + controls(0).Height + 0.007F * outlineBorderWeight / 2

        End With

        sec.LeftLine = ln

 

        ''畫最右面的right綫

        ''Right line

        ln = New Line

        ln.LineWeight = outlineBorderWeight

        ln.BringToFront()

        section.Controls.Add(ln)

        With ln

            .X1 = controls(controlsNum - 1).Left + controls(controlsNum - 1).Width

            .Y1 = controls(controlsNum - 1).Top - 0.007F * outlineBorderWeight / 2

            .X2 = .X1

            .Y2 = controls(controlsNum - 1).Top + controls(controlsNum - 1).Height + 0.007F * outlineBorderWeight / 2

        End With

        sec.RightLine = ln

 

        Return sec

End Function

其中SectionLines 結構和DrawLine方法可以寫成共通的,sub1,sub2,sub3都會用到.

這裡定義一個SectionLines的用途是,可以對返回的四根線進行處理。

<!--[if !vml]--><!--[endif]-->

ok,效果是一樣的

 

5,在DrawLine方法中,已經實現了最外面的框線用粗線,裡面的框線用細線。

由於剛才定義了結構SectionLines,把畫好的線返回給了它,所以要控制線條,就很方便了。

比如sub1的GroupHeader中,”科目”的bottom線和”番號””氏名”的top線是粗線,實際需要變成細線,這種效果都可以在代碼中通過SectionLines控制,代碼:


        Me.secGroupHeader1.BottomLine.LineWeight = 1

        Me.secGroupHeader2.TopLine.LineWeight = 1

看看效果:

<!--[if !vml]-->
<!--[endif]-->

仔細看的話,會發現groupheader的bottom line 的確變粗了,但其他3根線比較奇怪,雖然向內也變粗了,但向外卻沒變粗。

這是由於我們主模版上sub1的容器設定的寬度,正好是子模版裡“科目”控件的寬度,而我現在的畫線方法是在控件的邊上畫線,線條有一半的粗細被遮掉了。

解決方法:子模版中,控件left,top,預留線粗的一半距離,然後把整個子模版的ReportWidth加上線粗的偏移量。1單位的線粗,轉換到Inch是0.007。改動的代碼如下:


    Private Sub sub1_ReportStart(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.ReportStart

 

       ''

       ''

 

        Me.lbl1.Left = 0.007

        Me.lbl1.Top = 0.007

Me.PrintWidth = Me.lblName.Left + Me.lblName.Width +0.007F

 

        Me.Detail.Height = Me.txtID.Top + Me.txtID.Height + 0.007F

       ''

       ''

     End Sub

 

    Public ReadOnly Property ReportWidth() As Single

        Get

            Return Me.txtID.Width + Me.txtName.Width + 0.007F

        End Get

End Property

效果:

<!--[if !vml]-->
<!--[endif]-->

由於bottom和right和其他區域控件的線重疊了,所以看上去比較粗,可以把其他線隱藏掉(比如把sub2的left 線隱藏掉)

 

然後,用相同的方法弄好sub1的detail,以及sub2,sub3。出來這樣的效果:

<!--[if !vml]-->
<!--[endif]-->

 

6,整個帳票top,left,right的粗線畫好了,現在有個需求是detail中每5行畫一條粗線。

       直接給detail中控件的bottom畫粗線當然不可以,那會使得detail中每一行都變成粗線。

我們項目中的做法是:

       1)在組織數據源時,為數據源增加一個字段,用來判斷改行是印刷粗線還是細線。

比如sub1的數據源

番號

1

Tony

2

Zhu

3

Li

4

Zhang

5

Zha

6

Sun

增加一個字段,變成:

番號

氏名

LineFlag

1

Tony

0

2

Zhu

0

3

Li

0

4

Zhang

0

5

Zha

1

6

Sun

1

5的這一行印刷粗線,6由於是最後一行了,也要印刷粗線。

       2)數據源有了這個字段,然後在detail中放一個隱藏的textbox,邦定LineFlag

<!--[if !vml]-->
<!--[endif]-->

       3)Detail_BeforePrint事件中根據lineflag的值,來判斷是否要把該Detail下的控件的bottom線變粗


    Private Sub Detail_BeforePrint(ByVal sender As Object, ByVal e As System.EventArgs) Handles Detail.BeforePrint

        If Me.txtLineFlag.Text = "1" Then

            Me.secDetail.BottomLine.LineWeight = 2

        End If

    End Sub

 

 

4)最後的

 

 

7,這節就講到這裡。

AR裡線框的處理的確很麻煩。

不過在我們項目中,像DrawLine這種方法,以及5行粗線的方法,都做好了共通方法。而且大部分功能都寫在了基類裡,對於開發帳票的同學來說,只管調用方法就可以了,具體這些個方法是怎麼實現的,可以不用理睬。當然,為了更深的理解,有空也可以研究一下。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved