在我使用AR的過程當中,碰到最大的困難,不是數據的組織(雖然也很麻煩),而是畫面的布局,尤其是一些奇怪的線線框框,常常會為了一些特殊的線框要求,浪費很多時間調試。
本節我就把在項目的碰到的一些常見框線問題,簡單的進行一下分析。
1,帳票式樣,還是上節那張帳票。
該帳票的框線要求是:3個sub模版的四周要求粗線;Detail中的紀錄,要求每5行為粗線。
2,對於一個textbox或label等控件,初始狀態是沒有邊框的(就像圖中的”成績一覽表”這個控件),為控件提供邊框,一般有2種方法。
1)給控件設置border(right click控件,選border),這樣可以很方便的給控件設置4條邊框。
當然,也可以代碼中控制:
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邊擴張或縮小的,如圖:
<!--[endif]-->
這樣就會產生一個問題,如圖:
<!--[endif]-->
用的是方法1),由於border向2邊擴張,所以產生了字和框線重疊的問題。這在控件比較小,而框線特別粗的情況下會發生。
為了解決這個問題,我們有一種偏移控件的方法:
用方法2),把線畫在控件的外面,比如要在控件top上畫一條4單位寬的線,則就在控件上2單位高度的地方畫線,這條線會向上和向下各擴張2單位,這樣,線的下部正好和控件的頂部碰到,而又不會發生重疊的現象。當然,用這種方法的話,需要控制好控件之間的間距,否則2個控件之間的框線會互相重疊。
恩,我在這裡僅僅提供一個思路,具體怎麼做自己可以實踐一下。我下面的示例沒有用這種偏移控件的方法,只是簡單的在控件上畫線而已。
4,改造example10,改成方法2)畫線(直接在控件上畫線了,沒有去設置控件的偏移)
先把sub1,sub2,sub3上面控件的border都去掉,然後再代碼中動態生成line(示例代碼為sub1.vb)
其中SectionLines 結構和DrawLine方法可以寫成共通的,sub1,sub2,sub3都會用到.
這裡定義一個SectionLines的用途是,可以對返回的四根線進行處理。
ok,效果是一樣的
5,在DrawLine方法中,已經實現了最外面的框線用粗線,裡面的框線用細線。
由於剛才定義了結構SectionLines,把畫好的線返回給了它,所以要控制線條,就很方便了。
比如sub1的GroupHeader中,”科目”的bottom線和”番號””氏名”的top線是粗線,實際需要變成細線,這種效果都可以在代碼中通過SectionLines控制,代碼:
Me.secGroupHeader1.BottomLine.LineWeight = 1
Me.secGroupHeader2.TopLine.LineWeight = 1
看看效果:
<!--[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
效果:
<!--[endif]-->
由於bottom和right和其他區域控件的線重疊了,所以看上去比較粗,可以把其他線隱藏掉(比如把sub2的left 線隱藏掉)
然後,用相同的方法弄好sub1的detail,以及sub2,sub3。出來這樣的效果:
<!--[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
<!--[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行粗線的方法,都做好了共通方法。而且大部分功能都寫在了基類裡,對於開發帳票的同學來說,只管調用方法就可以了,具體這些個方法是怎麼實現的,可以不用理睬。當然,為了更深的理解,有空也可以研究一下。