Attachment: RSSforWPFWithUserControl.zip
At the moment new programming technologies appear almost every day. New technologies provide developers with wider abilities designed to create applications with more sophisticated user interface and extended functionality. One of such technologies is WPF. Its main advantages are:
- Use of DirectX as a technology for displaying graphics instead of used in Windows Forms and out of date GDI. It allows displaying of effects and complicated animation with quite high performance.
- Work can be easily divided between designers and developers. WPF has less limitation for designers who can quickly setup all interface elements: from buttons to tables.
- New class structure, dynamic properties and events.
- Ability to develop applications using markup and code of the programming part. Markup (XAML language) is used to implement application appearance and functional part is described in any .Net compatible programming language.
- WPF contains a rich set of panels, and it helps to reduce time and effort required to position elements on the form, as they cover almost all necessary variants.
But in spite of all advantages, there are some problems in using WPF; a lot of convenient controls and tools are designed for Windows and the use of these tools streamlines development of high-quality applications. And developers can’t use these tools in WPF by just placing them on the form. Creation of controls with similar features takes quite a lot of time as their development for Windows Forms could have taken several years. On the other hand it isn’t reasonable to refuse using them at all. That is why it is possible to use any Windows Forms controls (Control shall mean classes inherited from System.Windows.Forms.Control in WPF along with new technology features. There is a special container System.Windows.Forms.Integration.WindowsFormsHost designated to use Windows Forms controls on WPF pages. In order to use this element, you need to do the following steps:
- Create new WPF application
- Add to the project a reference to the WindowsFormsIntegration dll. It will allow you to get access to the WindowsFormsHost container
- Add to the project a reference to the dll containing Windows Forms control.
- Place WindowsFormsHost element onto WPF page.
- Add WindowsForms element into the child elements of the WindowsFormsHost.
After you go through all the steps, you will be able to use any WinForms control on the WPF page delivering the same functionality as on Windows forms, probably with slight limitations. To have an ability to apply to this control from the window code-behind file it is necessary to know its x:Name attribute. After that you will be able to apply to the control by its name from code.
Let us consider using controls from the .Net ModelKit Suite library on WPF pages. The library provides wide abilities to create reports, charts, pivot tables, gauges, etc. It is developed for Windows Forms and it is also possible to use it in Web and Silverlight applications, but none of the components can be used directly in WPF. So, let’s see how to use WindowsFormsHost for some of the components included in the suite.
We will create a simple report with the use of component included into the .Net ModelKit Suite library. The report will be displayed on the WPF page. To fulfill this task you need to make the following steps:
Create WPF project
Add references to PerpetuumSoft.Reporting and PerpetuumSoft.Framework dlls
Add the UserControl element to the project. This element will be a wrapper for report elements.
Place the DataSet onto the UserControl. This element will store report data.
Run DataSet.Tabels property editor, add a new table to the DataSet and set its name, for example, “Customers”.
Run Tabels.Columns property editor, add 2 columns to the table: “Name” and “Phone”.
Place ReportManager onto the form. This element is used to store information on report templates. It is possible to set data sources using this element.
Double click on the ReportManager to run its editor. Go to the Data sources tab.
It is necessary to add a data source. Click the “Add” button. In the appeared window, you need to set data source name and select the data source itself from the list. Select dataSet1.Customers table as a data source value.
Click the “New document” button in the report designer and in the appeared window select “Standard report”. Report wizard will run.
Add to the handler of OnLoad event of the UserControl code of filling report data source. For example, you can use the following code:
DataRow row = dataTable1.NewRow();
row["Name"] = “Johnson Leslie”;
row["Phone"] = “613-442-7654″;
dataTable1.Rows.Add(row);
row = dataTable1.NewRow();
row["Name"] = “Fisher Pete”;
row["Phone"] = “401-609-7623″;
dataTable1.Rows.Add(row);
row = dataTable1.NewRow();
row["Name"] = “Brown Kelly”;
row["Phone"] = “803-438-2771″;
dataTable1.Rows.Add(row);
After you added this code, you need to add code to prepare the report. You can do it using ReportSlot.Prepare method.
inlineReportSlot1.Prepare();
Place ReportViewer onto the UserControl. This element is used to display reports. It is necessary to set its Source property to the required InlineReportSlot.
Add namespace containing UserControl to the XAML markup of the xml window:
xmlns:userControl=”clr-namespace:RSSforWPFWithUserControl”
Add the WindowsFormsHost element to the form by placing the following code into the container body:
<WindowsFormsHost
HorizontalAlignment=”Stretch”
VerticalAlignment=”Stretch”>
</WindowsFormsHost>
Add UserControl to its content:
<userControl:ReportUserControl/>
Run application and see the result.
It is preferable to execute data preparation and report building on the UserControl. It allows using all available report functionality, such as DesignTime Designer, automatic saving of reports in the application code, binding to data sources, etc.
But besides this solution, there is another way to use Windows controls in WPF. It is possible to place such elements directly in WindowsFormsHost. There are some limitations using this approach.
In order to view reports, it is necessary to place ReportViewer onto WPF page. You can do it using WindowsFormsHost element. But here you will face a problem of how to create and edit report templates and connect to data sources. It is impossible to place ReportManager onto WPF page as we placed ReportViewer, as it is a descendant from the System.ComponentModel.Component class. The problem can be solved in the following way.
In spite it is impossible to run ReportDesigner in design time to edit reports, there is always an ability to run it in runtime, using the ReportSlot.DesignTemplate method. ReportSlot is created dynamically in this case. After you made all necessary changes to the report template, it is possible to save it to a file. The file represents a usual xml file. There are two way of how to use it. The first one is to use InlineReportSlot. In this case you can just copy xml string from the template file and set this string as a DocumentStream property value. It is possible to use FileReportSlot and in this case it is just necessary to specify path to the file.
There is also a problem with data sources. If you use data sources built into a template, there are no problems; you can work with them as you did it on Windows forms. If it is impossible to set data source in this way, you can create ReportManager dynamically and add data sources there. Data source can be added using the Add function of the ReportManager.DataSources collection. You can use the following code:
reportManager.DataSources.Add(“dataSourceName”, dataSourceObject);
So, using the solutions described in the article provides the ability to use any Windows Forms control in WPF projects sometimes with slight limitations. But in spite of all limitations, this ability is actual and it will stay actual until equivalent controls are designed completely on WPF.
Download Report Sharp-Shooter…