How to make a report viewer on Avalonia and FastReport Open Source. Part 2
How to make a report viewer on Avalonia and FastReport
Open Source. Part 2
In the
first part of the article, we began developing a report viewer. We created a
toolbar and implemented the report loading and display.
To be
displayed, the report must be in fpx format. Then, we export it to png format
and display it in an Image object. Forms in Avalonia are encoded using XAML. It
would be logical to display the report in the same format, but FastReport Open
Source does not support export to XAML. Therefore, we will use the available
export in image format.
So, we
have already implemented the main function of the application - the display of
the selected report. But often a report consists of many pages, so the next
function that we need to implement is navigation through report pages. That is,
you need to implement controls that allow us to move between the pages of the
report. To do this, we already have 4 buttons and a text field in the toolbar:
- Button: go to the first page;
- Button: go back to the page;
- Button: go to the next page;
- Button: go to the last page;
- Text field: page number.
It
remains to implement handlers for them. But at first we create one property:
private int currentPage = 0;
public int CurrentPage
{
get { return currentPage; }
set
{
if (value >= 0
&& value < pages.Count)
currentPage = value;
}
}
The
CurrentPage property contains the current page number. The initial value is 0,
that is, the first page. In the Set method, we check that the value is in the
range between 0 and the number of elements in the page list. As you remember,
in the XAML code of the page the tag for the button has a Click event:
<Button Name="First" Click="First_Click" Margin="5" Background="Transparent">
Now we will write the handlers for these events, they
are extremely simple:
private void
First_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
CurrentPage = 0;
SetImage();
}
Here we set the current page - the first page and load
the image corresponding to this page.
private void Prev_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
CurrentPage--;
SetImage();
}
Here the current page is reduced by one. That is, each
time you press the Prev button, one value will be taken from the current page
number. So, we’ll go back to the initial page until the CurrentPage value
reaches 0.
private void Next_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
CurrentPage++;
SetImage();
}
For the Next button, everything is the same, but
exactly the opposite. Here we increase the page number
by 1.
private void Last_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
{
CurrentPage = pages.Count - 1;
SetImage();
}
The Last button simply sets the maximum page number
equal to the number of pages in the page list.
Let's add a couple of lines of code to the SetContent
method:
private void SetContent(Report report)
{
DeleteTempFiles();
ex.ImageFormat = ImageExportFormat.Png;
ex.Resolution = 96;
Random rnd = new Random();
ex.Export(report, Directory.GetCurrentDirectory()
+ "/test." + rnd.Next(100) + ".png");
foreach (string file in ex.GeneratedFiles)
{
pages.Add(new Avalonia.Media.Imaging.Bitmap(file));
}
CurrentPage = 0;
}
In the beginning, we've added a call to the function
remove unnecessary export files left over from previous times.
And in the last line, we set the value of CurrentPage
to 0. This is necessary in case you, for example, are viewing report page
number 3 and want to load another report. The SetContent method will load the
report and set the first page.
Do you remember how the image installation method
looked like? Here it is:
public void SetImage()
{
img.Source = pages[0];
}
In this form, it displays only the first page. But now
at our disposal property CurrentPage. Let's refine the method so that it sets
the current page:
public void SetImage()
{
img.Source = pages[CurrentPage];
img.Height = imHeight;
img.Width = imWidth;
PageNumber.Text = (CurrentPage + 1).ToString();
}
In addition to loading the current image, we set the
height and width of the image. The height and width values are equal to the initial
height and width of the image, which we will save, for example, in the window
constructor:
private double imHeight;
private double imWidth;
public MainWindow()
{
InitializeComponent();
imHeight = img.Height;
imWidth = img.Width;
}
This is necessary for returning to the initial
settings of the image when moving to another page of the report in case of scaling
has been applied, which we will soon implement too.
But let’s back to SetImage method. In the last line we
set the current number in the text field. Thus, we will always know which
report page is currently displayed.
Since we started working with PageNumber, let's
implement the KeyDown event handler: private void
PageNumber_KeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
if (int.Parse(PageNumber.Text)
> 0)
{
CurrentPage = int.Parse(PageNumber.Text) - 1;
SetImage();
}
}
}
If the Enter button is pressed, the report page with
the number entered in the PageNumber text box will be loaded.
We have only two non-working buttons: zoom in and out.
Implement the Click event for the Zoom_in button:
private void
Zoom_in_Click(object sender, RoutedEventArgs e)
{
if (ex != null)
{
ex.ImageFormat = ImageExportFormat.Png;
ex.Resolution += 25;
ex.PageNumbers =
(CurrentPage + 1).ToString();
ex.Export(Report, Directory.GetCurrentDirectory() + "/testZoom.png");
if
(CurrentPage >= 0 && CurrentPage < pages.Count)
img.Source = LoadImage(Directory.GetCurrentDirectory() + "/testZoom.png");
PageNumber.Text =
(CurrentPage + 1).ToString();
}
img.Width += 50;
img.Height += 50;
}
In order to make the image appear sharp when zoomed,
it is necessary to increase its resolution. And for this you need to do a new
export. But if there are many pages in the report, exporting the entire report
again will not be the best solution. It is much faster to export the current
page. Therefore, in this method, we export the current page with an increased
resolution and save it to a temporary file testZoom.png. Then we load this
image into the Image object. We do the zooming by increasing the height and
width of the image.
We create a similar handler for the Zoom_out button:
private void
Zoom_out_Click(object sender, RoutedEventArgs e)
{
if (ex != null)
{
ex.ImageFormat = ImageExportFormat.Png;
ex.Resolution -= 25;
ex.PageNumbers =
(CurrentPage + 1).ToString();
ex.Export(Report, Directory.GetCurrentDirectory() + "/testZoom.png");
if (CurrentPage >= 0 && CurrentPage <
pages.Count)
img.Source = LoadImage(Directory.GetCurrentDirectory() + "/testZoom.png");
PageNumber.Text =
(CurrentPage + 1).ToString();
}
img.Width -= 50;
img.Height -= 50;
}
It's all
the same as in the previous method, only we do not increase the resolution, but
decrease it. Also reduce the height and width of the image object.
Now
let's test our application. Run it.
Using the
"Open" button with an open folder icon, we select the report file in
the dialog box. Press the button to go to the last page of the report:
Now let's
try the zoom function. Press several times on the enlargment button:
And now
reduce the size of the image:
We also
check the function of switching to the desired report page by entering the
number in the text field:
That's all.
I hope this simple application will help you to use FastReport.OpenSource in
your Avalonia applications.
Comments
Post a Comment