C# - ReportViewer - 使类不是静态的

时间:2016-05-16 19:17:13

标签: c# wpf reportviewer

我有一个类DependencyReportViewer,它对应于在我的程序中创建一个ReportViewer控件。这个课程很完美。在XAML中,我们仅为每个报告定义此行:

  <ctr:DependencyReportViewer EmbeddedReportName="Program.View.Reports.ReportName.rdlc" ReportData="{Binding ReportData}"/>

班级的第一部分:

<WindowsFormsHost x:Class="Program.View.Controls.DependencyReportViewer"
        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" 
        mc:Ignorable="d"
        d:DesignHeight="300" d:DesignWidth="300"
        IsVisibleChanged="WindowsFormsHost_IsVisibleChanged">
</WindowsFormsHost>

班上最糟糕的部分:

public partial class DependencyReportViewer : WindowsFormsHost
{
    private static ReportViewer ReportViewer = new ReportViewer();
    private static int ReportIsRunning = 0;

    static DependencyReportViewer()
    {
        DependencyReportViewer.ReportViewer.SetDisplayMode(DisplayMode.PrintLayout);

        try
        {
            RenderingExtensions = ReportViewer.LocalReport.ListRenderingExtensions();
        }
        catch (Exception)
        {
            RenderingExtensions = new RenderingExtension[0];
        }

        ReportViewer.ReportError += ReportViewer_ReportError;
    }


    public static RenderingExtension[] RenderingExtensions { get; private set; }

    public static readonly RoutedEvent ReportDoneEvent = EventManager.RegisterRoutedEvent("ReportDone", RoutingStrategy.Bubble,
        typeof(RoutedEventHandler), typeof(DependencyReportViewer));
    public event RoutedEventHandler ReportDone
    {
        add { AddHandler(ReportDoneEvent, value); }
        remove { RemoveHandler(ReportDoneEvent, value); }
    }

    public string EmbeddedReportName
    {
        get { return (string)GetValue(EmbeddedReportNameProperty); }
        set { SetValue(EmbeddedReportNameProperty, value); }
    }
    public static readonly DependencyProperty EmbeddedReportNameProperty = DependencyProperty.Register("EmbeddedReportName",
        typeof(string), typeof(DependencyReportViewer));

    public Tuple<IEnumerable<Tuple<string, IEnumerable>>, IEnumerable<Tuple<string, string>>> ReportData
    {
        get { return (Tuple<IEnumerable<Tuple<string, IEnumerable>>, IEnumerable<Tuple<string, string>>>)GetValue(ReportDataProperty); }
        set { SetValue(ReportDataProperty, value); }
    }
    public static readonly DependencyProperty ReportDataProperty = DependencyProperty.Register("ReportData",
        typeof(Tuple<IEnumerable<Tuple<string, IEnumerable>>, IEnumerable<Tuple<string, string>>>), typeof(DependencyReportViewer),
        new FrameworkPropertyMetadata(null, ReportData_Changed));


    private static void ReportData_Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var sts = Interlocked.CompareExchange(ref ReportIsRunning, 1, 0);
        if (sts != 0)
            return;

        var rv = (DependencyReportViewer)d;
        var data = (Tuple<IEnumerable<Tuple<string, IEnumerable>>, IEnumerable<Tuple<string, string>>>)e.NewValue;

        RenderingCompleteEventHandler evt = null;
        evt = (sender, rea) =>
        {
            ReportViewer.RenderingComplete -= evt;
            sts = Interlocked.Exchange(ref ReportIsRunning, 0);
            if (sts == 1)
                rv.RaiseEvent(new RoutedEventArgs(ReportDoneEvent));
        };
        ReportViewer.RenderingComplete += evt;

        DependencyReportViewer.ReportViewer.Reset();
        DependencyReportViewer.ReportViewer.LocalReport.ReportEmbeddedResource = null;
        if (data != null)
        {
            DependencyReportViewer.ReportViewer.LocalReport.SetBasePermissionsForSandboxAppDomain(new System.Security.PermissionSet(System.Security.Permissions.PermissionState.Unrestricted));

            DependencyReportViewer.ReportViewer.LocalReport.ReportEmbeddedResource = rv.EmbeddedReportName;

            var l = new List<ReportParameter>();
            foreach (var item in data.Item2)
            {
                l.Add(new ReportParameter(item.Item1, item.Item2));
            }
            DependencyReportViewer.ReportViewer.LocalReport.SetParameters(l);

            foreach (var item in data.Item1)
            {
                var rds = new ReportDataSource(item.Item1);
                rds.Value = item.Item2;
                DependencyReportViewer.ReportViewer.LocalReport.DataSources.Add(rds);
            }
        }
        DependencyReportViewer.ReportViewer.RefreshReport();
    }

    private static void ReportViewer_ReportError(object sender, ReportErrorEventArgs e)
    {
        Interlocked.Exchange(ref ReportIsRunning, 0);
    }


    public DependencyReportViewer()
    {
        InitializeComponent();
    }

    private void WindowsFormsHost_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
    {
        if ((bool)e.NewValue)
        {
            this.Child = DependencyReportViewer.ReportViewer;
        }
        else
        {
            DependencyReportViewer.ReportViewer.Reset();
            DependencyReportViewer.ReportViewer.LocalReport.ReportEmbeddedResource = null;
            DependencyReportViewer.ReportViewer.LocalReport.DataSources.Clear();
            DependencyReportViewer.ReportViewer.RefreshReport();
            this.Child = null;
        }
    }
}

问题是,只有当我们只打开一个带有此ReportViewer的UserControl时,此代码才能正常工作。如果我们打开两个或更多控件,那么最后一个打开的控件将接管ReportViewer。换句话说,可以同时打开一个ReportViewer。

现在我希望能够使用多个报表查看器打开多个控件。我得到的问题是这个类是静态的。当我们定义一个新控件时,则在“this.Child = DependencyReportViewer.ReportViewer;”中我们只是将此查看器重置为最新控件。

但是写这篇文章的人的技能比我现在的要高得多。我多次尝试使用XamlParseException将此类设置为非静态。如何将此类转换为非静态?

0 个答案:

没有答案