Blogs

The Progress Bar - DevExpress XPF Blog

May 2010 - Posts

  • WPF Data Grid – Using Fixed Columns

         

    The fixed columns functionality can be used to anchor columns to the left or right edge of the grid view so that they remain “fixed” regardless of content being scrolled sideways. While this is not a new feature to the 2010.1 release, the DevExpress Data Grid for WPF (DXGrid) now features an entry in the context menu of column headers to enable the end-user to create or remove fixed columns at runtime.

    Check out this short video on the DevExpress Channel that demonstrates how to use the context menu item as well as how to specify fixed columns manually at design time:

    WPF Grid - Fixed Columns Video

  • WPF Data Grid Control – Better Design Time Experience in 2010.1

         

    One of the advantages of a RAD IDE is that you can design and customize your application quickly without having to spend too much time in code to setup the redundant visual aspects. While the Visual Studio IDE provides a designer for all of the supported .NET platforms, ease of use comes down to the design time functionality provided by the individual control in question.

    While simple controls like buttons and textboxes don’t need much design-time support, complex components like the DevExpress Data Grid for WPF (DXGrid) need to provide an intuitive, yet functional design time experience for developers. This is an area where we continue to make improvements and we are excited to announce that with the 2010.1 release, we have greatly enhanced the design time experience of the DXGrid Control.

    To make common tasks more accessible, we have created the Quick Customization Panel which allows you to change the grid’s view, populate a view, create new columns, or add in-place editors to existing columns.

    WPF Grid - Customization Panel

    The functionality provided by the Quick Customization Panel is similar to the one found in the WinForms version of our grid control, the XtraGrid.

    The panel can also be minimized if you have less available screen real-estate and need to see more of your grid’s content:

    WPF Grid - Customization Panel Minimized

    You no longer need to modify column order through code or using the Columns Collection Editor. You can simply select a column header, drag it to the desired location and let go of the left mouse button. All the changes are automatically applied to the XAML markup. Columns can also be clicked to apply sorting to the data, or dragged to the group panel available above the grid view.

    WPF Grid - Column Customization

    And finally, in case you missed one of my previous posts, the Expression Editor for Unbound Columns can also be invoked at design-time.

    Also check out the following video demonstrating the design time enhancements to the DXGrid control:

    WPF Grid - Design Time Enhancements Video

  • WPF Data Grid – Introducing Hit Testing in v2010.1

         

    Yet another new feature found in 2010.1 release of the DXGrid control is Hit Testing support. Just like its WinForms counterpart, the WPF Grid now exposes an API that enables you to determine the element located a specific point of the control.

    As shown in the following screenshot, this can be used to provide additional hints within your application.

    WPF Grid - Hit Testing

    You can also use the available information to process clicks and handle drag-and-drop operations.

    To learn how to implement hit testing support in your application, check out this short video on the DevExpress Channel:

    WPF Grid - Hit Testing Video

  • WPF Data Grid – Expression Editor for Unbound Columns – 2010.1

         

    With the availability of DXperience 2010.1, I’d like to highlight yet another feature that’s new to the DevExpress Data Grid Control for WPF (DXGrid). The WPF grid now features a built-in Expression Editor that can be used to visually build complex expressions that can be applied to unbound columns.

    The Expression Editor can be invoked at design-time and also be made available at runtime to enable end-user customization of expressions. Click on the image below and check out the short video that demonstrates how to enable the Expression Editor and use it to create an expression for an unbound column:

    WPF Grid - Expression Editor

  • WPF Chart Control – Financial Chart, Chart Titles and Constant Lines – 2010.1

         

    Continuing the series of posts on new features for our controls, let’s turn to the DevExpress Chart Control for WPF (DXCharts). This is a powerful charting package that enables you to implement advanced charting solutions in your WPF application projects.

    For this blog post, I decided to create a financial chart sample that most people can relate to (or understand). The following topics are covered in this post:

    • Creating an intraday financial (candlestick) chart using data from an Access database
    • Adding a title to the chart NEW
    • Using the new Constant Lines feature in DXCharts to indicate the daily highs and lows as well as the previous close of the market instrument. NEW

    For this project, I’m using the S&P 500 Index’s intraday data in 5 minute intervals (5-min ticks). I’ve attached the data as well as the sample project to this post. Keep in mind the data is simply there for demo purposes and should not be used to make investment decisions.

    There, with the disclaimer out of the way, let’s dive into the project...

    You’ll need to start by adding the database as a data source for your project. So if you want to replicate everything in this sample, you’d need to add the Access database using the Data Source Configuration Wizard that can be invoked via the “Data –> Add New Data Source” menu entry. The columns we need are “Time”, “Open”, “High”, “Low”, and “Close”.

    Once that’s done, add a DXCharts control to the WPF window. You can add a title to the chart using the following code:

       1: <dxc:ChartControl Name="chartControl1">
       2:     <dxc:ChartControl.Titles>
       3:         <dxc:Title Content="S&amp;P 500 Index (SPX) - May 18, 2010" HorizontalAlignment="Center" />
       4:     </dxc:ChartControl.Titles>
       5: </dxc:ChartControl>

    You can have multiple titles that dock to the top, bottom, or sides of the chart control. In this case, I only need one title to be displayed at the top.

    Now let’s add the candlestick series and customize it. The end-result of the XAML should look like this:

       1: <dxc:ChartControl Name="chartControl1">
       2:     <dxc:ChartControl.Titles>
       3:         <dxc:Title Content="S&amp;P 500 Index (SPX) - May 18, 2010" HorizontalAlignment="Center" />
       4:     </dxc:ChartControl.Titles>
       5:     <dxc:ChartControl.Diagram>
       6:         <dxc:XYDiagram2D>
       7:             <dxc:XYDiagram2D.AxisY>
       8:                 <dxc:AxisY2D>
       9:                     <dxc:AxisY2D.Range>
      10:                         <dxc:AxisRange MaxValue="1150" MinValue="1110" />
      11:                     </dxc:AxisY2D.Range>
      12:                 </dxc:AxisY2D>
      13:             </dxc:XYDiagram2D.AxisY>
      14:             <dxc:XYDiagram2D.AxisX>
      15:                 <dxc:AxisX2D DateTimeGridAlignment="Minute" DateTimeMeasureUnit="Minute">
      16:                     <dxc:AxisX2D.DateTimeOptions>
      17:                         <dxc:DateTimeOptions Format="ShortTime" />
      18:                     </dxc:AxisX2D.DateTimeOptions>
      19:                 </dxc:AxisX2D>
      20:             </dxc:XYDiagram2D.AxisX>
      21:             <dxc:XYDiagram2D.Series>
      22:                 <dxc:CandleStickSeries2D Name="SPXSeries" ArgumentScaleType="DateTime"
      23:                                          ArgumentDataMember="Time" OpenValueDataMember="Open"
      24:                                          HighValueDataMember="High" LowValueDataMember="Low"
      25:                                          CloseValueDataMember="Close" CandleWidth="2">
      26:                     <dxc:CandleStickSeries2D.Label>
      27:                          <dxc:SeriesLabel Visible="False" />
      28:                     </dxc:CandleStickSeries2D.Label>
      29:                 </dxc:CandleStickSeries2D>
      30:             </dxc:XYDiagram2D.Series>
      31:         </dxc:XYDiagram2D>
      32:     </dxc:ChartControl.Diagram>
      33: </dxc:ChartControl>

    Finally, I need to bind the chart to data and draw the constant lines:

       1: // Required assembly reference
       2: using DevExpress.Xpf.Charts;
       3:  
       4:  
       5: ConstantLineCollection ConstantLines { get { return ((XYDiagram2D)chartControl1.Diagram).AxisY.ConstantLines; } }
       6:  
       7: public MainWindow() {
       8:     InitializeComponent();
       9:  
      10:     // Bind the chart series to data
      11:     SPXSeries.DataSource = new SPXDataSetTableAdapters.IntradayTableAdapter().GetData();
      12:  
      13:     // Draw the constant lines for the daily high, daily low and previous close values
      14:     ConstantLine highConstantLine = new ConstantLine(1148.66, "High");
      15:     highConstantLine.Brush = new SolidColorBrush(Colors.Green);
      16:     highConstantLine.Title.Foreground = new SolidColorBrush(Colors.Green);
      17:     ConstantLine lowConstantLine = new ConstantLine(1117.2, "Low");
      18:     lowConstantLine.Brush = new SolidColorBrush(Colors.Red);
      19:     lowConstantLine.Title.Foreground = new SolidColorBrush(Colors.Red);
      20:     ConstantLine closeConstantLine = new ConstantLine(1136.94, "Previous Close");
      21:     closeConstantLine.Brush = new SolidColorBrush(Colors.YellowGreen);
      22:     closeConstantLine.Title.Foreground = new SolidColorBrush(Colors.YellowGreen);
      23:     ConstantLines.AddRange(new ConstantLine[] { highConstantLine, lowConstantLine, closeConstantLine });
      24:     foreach (ConstantLine constantLine in ConstantLines) {
      25:         constantLine.ShowBehind = true;
      26:         constantLine.Title.Alignment = ConstantLineTitleAlignment.Far;
      27:     }
      28: }

    In a real-world application you will of course implement a routine to automatically select the highs and lows of the trading day, however as you can see from the code, I’ve manually entered the values to keep this example simple.

    And when I run the project, the end-result will look like this:

    WPF Charts

    UPDATE: We’ve also published a video tutorial that can be viewed here: http://tv.devexpress.com/DXChartsFinanceCharts.movie

  • WPF Data Grid – Filter Editor – 2010.1

         

    Starting with the 2010.1 release of DXperience, the DevExpress WPF Data Grid Control (DXGrid) features a built-in filter editor that allows you as well as your end-user to create complex filter criteria at runtime. Similar to the filter editor found in our WinForms and ASP.NET components, this control automatically detects the data type used in a data field and displays an appropriate editor to simplify creating filter conditions.

    So for example, here is a filter editor that is being used to create filter criteria using fields that contain date values:

    WPF Grid - Filter Editor

    To learn more, check out the following short video that demonstrates how to enable the filter editor and use it to apply a set of filter criteria at runtime:

    WPF Data Grid Filter Editor Video

  • WPF Project Wizard – Quick Project Setup using DevExpress Components v2010.1

         

    Wizards... everyone like them. In software, a wizard assists the user in completing tasks that would’ve been otherwise difficult to understand or simply time-consuming to manually implement. While we strive to make our controls as easy to use as possible, we decided to take an additional step and make it even easier to create projects that can be used as the base for advanced WPF applications. This not only saves you time by setting up the basic project settings, but it also provides you with a real example of how our WPF controls can be set up and customized. This is especially useful if you are new to using our products.

    To do this, we are introducing the WPF Project Wizard. To use this wizard, select the “DX WPF Application” project template which invokes the “Project Settings” window that looks like this:

    WPF Project Wizard

    This window allows you to select and customize DevExpress UI controls that you’d like included in your WPF application project.

    For a video walkthrough of the WPF Project Wizard, check out the following short video:

    WPF Project Wizard Walkthrough Video

  • Silverlight Rich Text Edit Control (RTF Control) – Mail Merge Functionality

         

    In addition to a host of advanced features provided by  the DevExpress Rich Text Edit for Silverlight (AgRichEdit), the control also provides mail merge functionality. Once a big bullet-point in the features list of desktop word processing applications, mail merge can now be easily added to your Silverlight application, giving your end-users the power to create data-bound documents that are generated and updated on-the-fly based on records in a database.

    In this post, I’ll take a look at a simple example to demonstrate how easy it is to add a data source and use a mail-merge document that will access the data and display each record at runtime.

    First, I need to specify a data source. In this case, I’m using an XML file that I’ve copied to my Silverlight project. The XML file along with all the code for the example will be attached to the end of this post.

    The Employees.cs file will load the XML file so it can be set as the data source for the MailMerge property of the RichEdit control.

       1: using System;
       2: using System.IO;
       3: using System.Xml.Serialization;
       4: using System.Collections.Generic;
       5: using DevExpress.XtraRichEdit.Services;
       6:  
       7: namespace SilverlightRichEdit
       8: {
       9:     public class Employees
      10:     {
      11:         public int EmployeeID { get; set; }
      12:         public string LastName { get; set; }
      13:         public string FirstName { get; set; }
      14:         public string Title { get; set; }
      15:         public string TitleOfCourtesy { get; set; }
      16:         public DateTime BirthDate { get; set; }
      17:         public DateTime HireDate { get; set; }
      18:         public string Address { get; set; }
      19:         public string City { get; set; }
      20:         public string Region { get; set; }
      21:         public string PostalCode { get; set; }
      22:         public string Country { get; set; }
      23:         public string HomePhone { get; set; }
      24:         public string Extension { get; set; }
      25:         public double Salary { get; set; }
      26:         public bool OnVacation { get; set; }
      27:         public byte[] Photo { get; set; }
      28:         public string Notes { get; set; }
      29:         public int ReportsTo { get; set; }
      30:     }
      31:     [XmlRoot("NewDataSet")]
      32:     public class EmployeesData : List<Employees>
      33:     {
      34:         public static object DataSource
      35:         {
      36:             get
      37:             {
      38:                 XmlSerializer s = new XmlSerializer(typeof(EmployeesData));
      39:                 return s.Deserialize(typeof(EmployeesData).Assembly.GetManifestResourceStream(typeof(EmployeesData).Namespace + ".Resources.Employees.xml"));
      40:             }
      41:         }
      42:     }
      43:     public class DBUriStreamProvider : IUriStreamProvider
      44:     {
      45:         static readonly string prefix = "dbimg://";
      46:         List<Employees> employees;
      47:  
      48:         public DBUriStreamProvider(List<Employees> employees)
      49:         {
      50:             this.employees = employees;
      51:         }
      52:  
      53:         #region IUriStreamProvider Members
      54:         public Stream GetStream(string uri)
      55:         {
      56:             uri = uri.Trim();
      57:             if (!uri.StartsWith(prefix))
      58:                 return null;
      59:             string strId = uri.Substring(prefix.Length).Trim();
      60:             int id;
      61:             if (!int.TryParse(strId, out id))
      62:                 return null;
      63:             Employees employee = FindEmployeeById(id);
      64:             if (employee == null)
      65:                 return null;
      66:             return new MemoryStream(employee.Photo);
      67:         }
      68:  
      69:         private Employees FindEmployeeById(int id)
      70:         {
      71:             foreach (Employees employee in employees)
      72:                 if (employee.EmployeeID == id)
      73:                     return employee;
      74:             return null;
      75:         }
      76:         #endregion
      77:     }
      78: }

    In the MainPage.xaml.cs code-behind file, I’ll add a reference to the following required namespace…

       1: using DevExpress.XtraRichEdit.Services;

    Finally, I need to create an instance of IUriStreamService and use it to register “EmployeesData” as a data stream provider (DBUriStreamProvider). EmployeesData is then set as the data source for the MailMerge functionality of the RichControl:

       1: private void richEdit1_Loaded(object sender, RoutedEventArgs e)
       2: {
       3:     IUriStreamService uriService = (IUriStreamService)richEdit1.RichControl.GetService(typeof(IUriStreamService));
       4:     uriService.RegisterProvider(new DBUriStreamProvider((List<Employees>)EmployeesData.DataSource));
       5:     richEdit1.RichControl.Options.MailMerge.DataSource = EmployeesData.DataSource;
       6: }

    Note that this code can be added in any event handler as long as richEdit1.RichControl has been loaded and can be referenced at runtime. It is not mandatory to set the datasource inside the loaded event.

     

    So now that I’m done, I can run the application and import an RTF file that I had prepared using an existing set of fields. By default, the merged data is not shown and has to be enabled using the “Mail Merge” menu:

    SL RTF Merged Data

    Once enabled, the end-result will look as follows:

    SL RTF Merged Data Result

  • Silverlight Rich Text Edit Control – Custom Syntax Highlighting

         

    In a previous blog post, I highlighted the new features of the AgRichEdit control in v2010.1. I would like to now switch gears and talk about a features that’s not new, but is probably not widely known: Custom Syntax Highlighting.

    So let’s say you are developing a Silverlight application to display and edit code, or perhaps you just need the application to automatically highlight specific keywords. Using the custom syntax highlighting feature, you can easily implement that functionality through code.

    Let’s take a look at a simple example where I can import a text file with a set of SQL queries and highlight keywords within the document. The end result will look like this:

    SL RTF Syntax Highlighting

    First and foremost, I’ll need references to the following namespace:

       1: using DevExpress.Xpf.RichEdit.Extensions;
       2: using DevExpress.XtraRichEdit.API.Native;
       3: using DevExpress.XtraRichEdit.Services.Implementation;

    I’ll then add a class that implements the ISyntaxHighlightService interface. Here I can define the list of keywords I would like to see highlighted and then specify the color that’ll be used to highlight the text.

       1: class MySyntaxHighlightServiceWrapper : ISyntaxHighlightService
       2: {
       3:     RichEdit control;
       4:     static string[] str;
       5:     List<int> paragraphHashes;
       6:     static MySyntaxHighlightServiceWrapper() {
       7:         str = new string[] { "INSERT", "SELECT", "CREATE", "TABLE", "USE", "IDENTITY", "ON", "OFF", "NOT", "NULL", "WITH", "SET" };
       8:         Array.Sort(str);
       9:     }
      10:     
      11:     public MySyntaxHighlightServiceWrapper(RichEdit control) {
      12:         this.control = control;
      13:         paragraphHashes = new List<int>();
      14:  
      15:     }
      16:     
      17:     public void ResetCache() {
      18:         paragraphHashes.Clear();
      19:     }
      20:  
      21:     public void Execute() {
      22:         Document doc = this.control.RichControl.Document;
      23:         int paragraphCount = doc.Paragraphs.Count;
      24:         for (int i = 0; i < paragraphCount; i++) {
      25:             HighlightParagraph(i);
      26:         }
      27:     }
      28:  
      29:     void HighlightParagraph(int paragraphIndex) {
      30:         Document doc = this.control.RichControl.Document;
      31:         Paragraph paragraph = doc.Paragraphs[paragraphIndex];
      32:         DocumentRange paragraphRange = paragraph.Range;
      33:         int paragraphStart = paragraphRange.Start.ToInt();
      34:         string text = doc.GetText(paragraphRange);
      35:         int hash = text.GetHashCode();
      36:         if (paragraphIndex < paragraphHashes.Count && paragraphHashes[paragraphIndex] == hash)
      37:             return;
      38:         int length = text.Length;
      39:         int prevWhiteSpaceIndex = -1;
      40:         for (int i = 0; i < length; i++) {
      41:             char ch = text[i];
      42:             if (Char.IsWhiteSpace(ch) || Char.IsPunctuation(ch)) {
      43:                 int wordLength = i - prevWhiteSpaceIndex - 1;
      44:                 if (wordLength > 0) {
      45:                     int wordStart = prevWhiteSpaceIndex + 1;
      46:                 string word = text.Substring(wordStart, wordLength);
      47:                 int index = Array.BinarySearch(str, word);
      48:                 DocumentRange range = doc.CreateRange(paragraphStart + wordStart, wordLength);
      49:                 CharacterProperties cp = doc.BeginUpdateCharacters(range);
      50:                 if (index >= 0)
      51:                     cp.ForeColor = Colors.Blue;
      52:                 else
      53:                     cp.ForeColor = Colors.Black;
      54:                     doc.EndUpdateCharacters(cp);
      55:                 }
      56:                 prevWhiteSpaceIndex = i;
      57:             }
      58:         }
      59:         for (int i = paragraphHashes.Count; i <= paragraphIndex; i++)
      60:             paragraphHashes.Add(String.Empty.GetHashCode());
      61:         paragraphHashes[paragraphIndex] = hash;
      62:     }
      63: }

    Finally, I need to register this as a service with the AgRichEdit control. I’ll do so in the Rich Text Editor’s Loaded event handler.

       1: private void richEdit1_Loaded(object sender, RoutedEventArgs e) {
       2:     ISyntaxHighlightService service = richEdit1.RichControl.GetService<ISyntaxHighlightService>();
       3:     MySyntaxHighlightServiceWrapper wrapper = new MySyntaxHighlightServiceWrapper(richEdit1);
       4:     richEdit1.RichControl.RemoveService(typeof(ISyntaxHighlightService));
       5:     richEdit1.RichControl.AddService(typeof(ISyntaxHighlightService), wrapper);
       6: }

    And Voilà! Now when you run the application, the rich text editor will parse the imported file and highlight the specified keywords using the color blue.

    The complete project for this sample is also attached to this post for reference.

  • Silverlight Rich Text Edit Control – New Features in v2010.1

         

    What started out as a concept to bring rich text editing to Silverlight has evolved to a full-featured editor, capable of providing Microsoft Word like editing functionality that can easily be integrated in your Silverlight Applications.

    The DevExpress Rich Text Edit Control for Silverlight (AgRichEdit) uses an advanced, true multi-threaded formatting engine that generates or renders document layout similar to Microsoft Word. The goal is to be able to create and share documents between the two platforms without the need to do any modifications. This concept is further enhanced with extensive file-format support for the Word DOCX, OpenDocument, HTML, MHT, EML, RTF, XML and or course the plain text format.

    Starting with version 2010.1, we are not only introducing full support for Visual Studio 2010 and Silverlight 4, but also enhancing the feature set of the control by implementing several new features. I’ll make a short list of the highlighted features here and talk about them in more detail in upcoming blogs and videos.

    Tables support

    SL4 RTF Tables

    Using the Rich Text Edit Control, you can now create and use tables in your documents, or import existing ones with tables that were created in another application. While the design-time editing functionality is still being improved, the rendering engine fully supports working with complex table layouts such as nested tables.

    Headers and Footers

    As you may have noticed in the screenshot above, the AgRichEdit now supports embedding headers and footers in your document. The above sample was actually created in Microsoft Word 2010 and imported into our RichEdit control. The headers and footers were correctly maintained when the document was resaved and re-imported into Word. We support 3 types of headers and footers: first page, odd page, and even page.

    Printing Support

    You can print the content of the RichEdit control as the control implements the Silverlight 4 printing API. The printing abilities at this point are only limited by the capabilities provided by the SL 4 printing API.

    External drag & drop

    Files can be opened by simply dragging the document from the local machine and dropping it unto the Silverlight RichEdit control.

    Custom Context Menu

    The right-click context menu now displays a Rich Edit specific menu with items that can also be customized using code. One use for the new context menu is the list of suggested spellings that are automatically displayed at the top of the menu when spell checking is enabled and a misspelled word is right-clicked.

    And finally…

    Formatted text can be copied/pasted from and to the new RichTextBox control that ships with Silverlight 4.

    Also, be sure to check out the video that demos some of the features I mentioned in this post: http://tv.devexpress.com/SLTextEditorNewFeatures.movie

  • Using the WPF Report Viewer - Reporting Suite in DXperience 2010.1

         

    As you may have heard, starting with version 10.1, we're introducing native report viewers for both WPF and Silverlight. The availability of these viewers enable you as a developer to target more platforms and reach a wider audience.

    Using the report viewer, the reports can be easily imported into and displayed in a WinForms, ASP.NET, WPF and Silverlight application. And the best part is: They’ll all look exactly the same.

    So while it’s possible to use the XtraReports Designer for Visual Studio to build reports in any project, the true portability and cross-platform compatibility of the product can not be demonstrated unless we create a report using the stand-alone End-User Reports Designer that ships with the XtraReports Suite.

    Using the designer, we can create a report that is bound to data and all of its layout and configuration information is independent of the Visual Studio-based designer:

    End-User-Designer

    At this point, the report can be previewed within the designer, saved as a “repx” file and distributed to your end-users. Your end-users can further modify the report using the same designer, the Visual Studio designer, or load it into the client application that you’ve developed. For this example, I’ll focus on the WPF Report Viewer and show the simplest way to load and preview an existing “repx” report file.

    To start, I’ve created a simple UI that can be used to load a repx file and display it in the WPF Report Viewer at runtime.

    MainWindow

    Switching to code view, I need to make sure that there is a using reference to the “DevExpress.Xpf.Printing” namespace:

       1: using DevExpress.Xpf.Printing;

    Finally, the following code uses the OpenFileDialog component to enable the user to browse for a repx file and loads it into the Report Viewer:

       1: private void button1_Click(object sender, RoutedEventArgs e) {
       2:     Microsoft.Win32.OpenFileDialog dlg = new Microsoft.Win32.OpenFileDialog { 
       3:           DefaultExt = ".repx", Filter = "XtraReport Layout (.repx)|*.repx" };
       4:  
       5:     if (dlg.ShowDialog() == true) {
       6:         textBox1.Text = dlg.FileName;
       7:         button2.IsEnabled = true;
       8:     }
       9: }
      10:  
      11: private void button2_Click(object sender, RoutedEventArgs e) {
      12:     DevExpress.XtraReports.UI.XtraReport report = new DevExpress.XtraReports.UI.XtraReport();
      13:     report.LoadLayout(textBox1.Text);
      14:     XtraReportPreviewModel model = new XtraReportPreviewModel(report);
      15:     DocumentPreviewWindow window = new DocumentPreviewWindow() { Model = model };
      16:     report.CreateDocument(false);
      17:     window.Show();
      18: }

    The report preview in WPF then looks like this:

    Preview

More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.