Saturday, August 15, 2015

Embed SSRS Report Into WPF Application Without ReportViewer

When you google how to embed SSRS report into WPF application, chances are you'd come across this page at least once:

Walkthrough: Using ReportViewer in a WPF Application

But what if you don't want to use any of Windows Form controls? ReportViewer is Windows Form control.

There is WPF WebBrowser control we potentially could use, but it doesn't have a ready built-in attribute that we could simply set an URL to, so there's an extra step needed before we can use it. An attached property will do this for us.

    public static class WebBrowserHelper
    {
        public static readonly DependencyProperty WebAddressProperty = DependencyProperty.RegisterAttached(
            "WebAddress", 
            typeof (string), 
            typeof (WebBrowserHelper), 
            new PropertyMetadata(OnWebAddressChanged));

        public static string GetWebAddress(DependencyObject dependencyObject)
        {
            return (string) dependencyObject.GetValue(WebAddressProperty);
        }

        public static void SetWebAddress(DependencyObject dependencyObject, string value)
        {
            dependencyObject.SetValue(WebAddressProperty, value);
        }

        private static void OnWebAddressChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            WebBrowser browser = d as WebBrowser;
            if (browser != null && e.NewValue != null)
            {
                string url = e.NewValue.ToString();
                browser.Navigate(url);
            }
        }
    }

To use it, simply call the attached property from WebBrowser and bind it to the SSRS URL in the ViewModel.


<UserControl x:Class="Views.WebBrowserView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:Views.Helpers"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300">   
    <Grid>
        <WebBrowser local:WebBrowserHelper.WebAddress="{Binding Path=SsrsUrl}" />
    </Grid>
</UserControl>

public class ViewModel
{
    public string SsrsUrl { get; set; }
}

And we're pretty much done.