饭饭TXT > 学习管理 > 《Visual Studio 2010 高级编程(英文出书版)》作者:Nick Randolph/等【完结】 > [Visual.Studio.2010.高级编程].Professional.Visual.Studio.2010.txt

第 99 页

作者:Nick Randolph/等 当前章节:15373 字 更新时间:2026-6-18 14:51

Dim customAssembly As Assembly = Assembly.Load(customAssemblyName)

Dim assemblyStrongName As StrongName = CreateStrongName(customAssembly)

reportEngine.AddFullTrustModuleInSandboxAppDomain(assemblyStrongName)

c#

string customAssemblyName = "CustomReportingFunctions, Version=1.0.0.0, " +

"Culture=neutral, PublicKeyToken=b9c8e588f9750854";

Assembly customAssembly = Assembly.Load(customAssemblyName);

StrongName assemblyStrongName = CreateStrongName(customAssembly);

reportEngine.AddFullTrustModuleInSandboxAppDomain(assemblyStrongName);

fiGure 30-30

Designing reports .

667

There are two things you will note from this code. The first is that you are loading the custom assembly

from the GAC using its name (in order to obtain its strong name so you can notify the reporting engine

that it’s trusted), including its version, culture, and public key token. This string can be obtained by

copying it from where you added the assembly reference to the report in its Report Properties dialog box.

The second is the use of the GetStrongName function to return the StrongName object, the code for

which is below:

Vb

Private Shared Function CreateStrongName(ByVal assembly As Assembly) As StrongName

Dim assemblyName As AssemblyName = assembly.GetName()

If assemblyName Is Nothing Then

Throw New InvalidOperationException("Could not get assembly name")

End If

' Get the public key blob

Dim publicKey As Byte() = assemblyName.GetPublicKey()

If publicKey Is Nothing OrElse publicKey.Length = 0 Then

Throw New InvalidOperationException("Assembly is not strongly named")

End If

Dim keyBlob As New StrongNamePublicKeyBlob(publicKey)

' Finally create the StrongName

Return New StrongName(keyBlob, assemblyName.Name, assemblyName.Version)

End Function

Code snippet CreateStrongName.vb

c#

private static StrongName CreateStrongName(Assembly assembly)

{

AssemblyName assemblyName = assembly.GetName();

if (assemblyName == null)

throw new InvalidOperationException("Could not get assembly name");

// Get the public key blob

byte[] publicKey = assemblyName.GetPublicKey();

if (publicKey == null || publicKey.Length == 0)

throw new InvalidOperationException("Assembly is not strongly named");

StrongNamePublicKeyBlob keyBlob = new StrongNamePublicKeyBlob(publicKey);

// Finally create the StrongName

return new StrongName(keyBlob, assemblyName.Name, assemblyName.Version);

}

Code snippet CreateStrongName.cs

668 .

chaPter 30 reporTing

Now when you run the report you will have the same output as when you embedded the code in the

report, but in a more reusable and maintainable form.

report layout

Generally reports are produced in order to be printed, therefore you must consider how the

printed report will look in your report design. The first thing to ensure is that the dimensions of

your report match the paper size that it will be printed on. Open the Report Properties window

via the Report . Report Properties menu. The selected tab will be the Page Setup tab, from which

you can select the paper size, the margins, and the orientation of the page (portrait or landscape).

Many reports tend to extend beyond one page, and it can be useful to show something at the

top and bottom of each page to show which company and report it belongs to, and where that

page belongs within the report (in case the pages are dropped, for example). So far you have been

dealing just with the body of the report, but you can add a page header and footer to the report

to use for these purposes. Page headers tend to be used for displaying the company logo, name,

and information about the company (like a letterhead). Page footers tend to be used to display

page numbers, the report title, and perhaps some totals for the information displayed on that page.

Add a page header to your report via the

Report . Add Page Header menu command.

This adds a page header area in the

report designer above the report body (see

Figure 30-31), which you can resize to your

needs, and upon which you can place various

controls such as textboxes and images. You

can even place other controls such as a Table

or Gauge, although it’s rare to do so. If

you drag a field from the Report Data tool

window directly onto the page header you will note that it creates a complex expression (as it does

on the report body), so add a table first if you want to display some totals, for example.

Adding a page footer is much the same

process. Select the Report . Add Page Footer

menu to add a page footer area in the report

designer below the body of the report

(see Figure 30 - 32 ).

You can use the built-in report fields to

display information such as the page number,

number of pages, report name, the time the

report was generated, and so on, which can be used anywhere in your report. You can find them in

the Report Data tool window, under the Built-in Fields category.

fiGure 30-31

fiGure 30-32

The value for the Report Name field is retrieved from the filename of the report

with the extension removed.

Designing reports .

669

Generally you will want to show the page numbers in the form as Page 1 of 6. However, the page

number and page count fields are separate, so it’s best to drop a textbox in the footer and drop both

fields in that:

Page [ & PageNumber] of [ & TotalPages]

The values in the square brackets will automatically turn into placeholders with the correct

expressions behind them (the & specifies that these are global variable references) that get the values

from the built-in fields. You can alternatively drag these fields from the Report Data tool window

into the textbox and add the static text in between.

Be careful that you don’t remove the page header or footer once you’ve created

it (by selecting Remove Page Header or Remove Page Footer from the Report

menu) because this will delete the content of the header/footer and adding it

back again won’t restore its content. There is no warning displayed when you

do this, so if you do so by accident use the Undo function to restore it to its

previous state.

One question you may now have is how to create report headers and footers (that only appear on

the first/last page of the report, rather than each page). An example of a report header would be to

display the title of the report and other report information at the top of the report (on the first page

only), and an example of a report footer would be to display some totals at the end of the report (on

the last page only).

The report designer doesn’t support report headers/footers as special areas of the report in the same

way it does for page headers/footers because you can simply include them in the body of the report.

By putting the report header content at the top of the body of your report it will only display once,

then it will display the content (which may expand to cover multiple pages), and finally at the

bottom of your report you can put the report footer content. The only issue to deal with is that you

won’t want the page header on the first page of your report (because you will only want the report

header), and you won’t want the page footer on the last page (because you will only want the report

footer). To do this, right-click your report header and select Header Properties from the menu. From

the General tab (which will be the one selected), uncheck the Print on First Page checkbox. The

process is much the same for the page footer: right-click your report footer, select Footer Properties

from the menu, and then uncheck the Print on Last Page checkbox.

The final thing you must consider with your report layout is where the page breaks will occur.

For example, you may want a table to appear all on the same page where possible rather than

half on one page and half on another. Or perhaps you have its data grouped, and you want each

group to start on a new page. You can do this by setting page break options on the controls that

support them (Table, Matrix, List, Rectangle, Gauge, and Chart). Each of these controls has the

PageBreak property (select the control in the report designer and find the property in the Properties

tool window). This gives you the option to start a new page before it displays the control, after it

displays the control, or both before and after it displays the control. You can set KeepTogether to

true so that if the output of the control stretches across two pages it will attempt to display it all on

670 .

chaPter 30 reporTing

the one page by starting it on the next page instead. When you are grouping data in a table, matrix,

or list, you can also set the page break options for the group. When you view the properties of a

group (right-click the group in the Row Groups pane at the bottom of the designer and select Group

Properties from the menu) you will note a Page Breaks tab. Here you can select whether there should

be a page break between each group, and you can also select whether there should be an additional

page break before and/or after each group.

subreports

Subreports is a feature that enables you to insert the contents of one report into another. You can

insert the contents (excluding headers and footers) of any report into another by adding a Subreport

control to your main report and setting its ReportPath property to the path of the other report

to display in that area. By merging a number of reports into a single output report you are able

to create quite complex report structures. Other uses of subreports include creating master-detail

reports, drill-down reports, and splitting reports into predefined “components” that can be used by

multiple reports — enabling each component to be defined once and used multiple times. This also

has the advantage that changes can be made in a single place and automatically picked up by the

other reports (such as a standard report header with company information, used by all the reports).

First look at a scenario where the contents of the subreport are not linked to the “master” report.

Create a new report, and simply put a textbox on it with some text. Now add a Subreport control to

your main report, and set the ReportName property to the filename of the other report (but without

the extension).

Unfortunately the report to be used as the subreport must be located in the same

folder as the main report.

When you run the project and view the report you will see that the contents of the subreport are

merged into the main report.

Getting a little more complicated now, hook up a data source to the subreport and show some data

in it (in a standalone fashion from the main report). The issue now is, because the data sources

aren’t shared between the main report and the subreport, how do you pass the data to that report?

You do this by handling the SubreportProcessing event on the LocalReport object in the code

that configures the Report Viewer control (discussed in full later in this chapter). You will need to

add an event handler for this event like so:

Vb

AddHandler reportViewer.LocalReport.SubreportProcessing, AddressOf ProcessSubreport

c#

reportViewer.LocalReport.SubreportProcessing += ProcessSubreport;

Designing reports .

671

and add a function for this event handler that adds the data to the

SubreportProcessingEventArgs object passed in as a parameter (including the name of the

dataset), like so:

Vb

Private Sub ProcessSubreport(ByVal sender As System.Object,

ByVal e As SubreportProcessingEventArgs)

e.DataSources.Add(New ReportDataSource("DataSetName", data))

End Sub

c#

private void ProcessSubreport(object sender, SubreportProcessingEventArgs e)

{

e.DataSources.Add(new ReportDataSource("DataSetName", data));

}

When you run the project now the subreport will be populated with data.

Now take a look at the slightly more complex scenario where what is displayed in the subreport is

dependent on data in the main report. Say, for example, the main report is displaying the details

of each customer, but you also want to show the orders each customer made in the last month

underneath their details using a subreport. So that the subreport knows which customer to retrieve

the order details for, you need to make use of Report Parameters.

Note that there are a lot of overheads in implementing this scenario in this way.

There will be multiple calls to the database — one for each customer to return

their order details, which will put strain on the database server. A better, more

efficient way for this scenario would be to return a joined customer details

+ orders dataset from the database, and use the Table control to group by

customer and display their order details. However, this scenario is just used as

an example of how to pass information from the main report to subreports.

Create a report (which will be the main report) to display the details of each customer (in a list),

and another report (the subreport) that displays the orders that a customer has made. Under the

customer details fields (but still in the list), add a Subreport control that points to the subreport

you created, and hook up the code-behind as previously described. What you will note is that

when handling the SubreportProcessing event to return the order details data to the subreport,

you need to know which customer to return the data for (the subreport will be rendered for each

customer, therefore this event handler will be called to return the order details for each customer).

This is where you need to create a Report Parameter for the subreport that the main report will use

to pass the current customer’s ID to it.

To add a new parameter to the subreport, go to the Report Data tool window, right-click the

Parameters folder, and select Add Parameter from the menu. Create the parameter with CustomerID

as its name, and set its data type to Integer.

672

.

chaPter 30 reporTing

目录
设置
设置
阅读主题
字体风格
雅黑 宋体 楷书 卡通
字体大小
适中 偏大 超大
保存设置
恢复默认
手机
手机阅读
扫码获取链接,使用浏览器打开
书架同步,随时随地,手机阅读
首 页 < 上一章 章节列表 下一章 > 尾 页