0

我正在按照 MVVM 模式制作 WPF 应用程序。

我有一个带有导航控件的窗口以及一个用于保存单个用户控件的占位符(内容控件)。主窗口的视图模型维护一个打开的子视图模型数组,并具有一个“当前视图”属性,该属性指向数组中的单个子视图模型。然后将此“CurrentView”属性绑定到主窗口上的 contentcontrol 占位符。视图模型都通过数据模板设置了特定的视图(用户控件)。

当“CurrentView”属性设置为子视图模型之一时,适当的用户控件视图将显示在主窗口的 contentcontrol 占位符中。一次只显示一个子视图模型,其余的只是放在数组中,等待通过设置为 CurrentView 属性来显示。

到目前为止,我对这种模式没有任何问题。它适用于所有标准 WPF 控件,没有任何问题。我的问题是只有当我的一个用户控件承载 WPF Crystal Report Viewer 时。

我可以将当​​前视图设置为具有水晶报表报告文档的视图模型。我加载报告文档并将其公开为公共依赖属性。此视图模型的数据模板化用户控件具有 WPF Crystal Report Viewer 控件。我已向报表查看器控件添加了一个附加属性,以允许我绑定到 .ViewerCore.ReportSource。我将视图模型中的报告文档绑定到附加属性,瞧!所有这些都按预期工作。我编译我的程序并导航到水晶报表查看器......它加载绑定的报表并正确显示它。

但是,现在,当我离开时(用不同的视图模型替换主窗口上的“CurrentView”属性)我得到一个错误。

起初,我得到“未设置属性:窗口”。经过一番搜索,我发现 Crystal Report Viewer 试图显示一个消息框,但不知道它的所有者窗口,所以它不能。为了解决这个问题,我将水晶报表查看器的所有者设置为用户控件加载事件中的主窗口。这摆脱了“属性未设置:窗口”错误。

我重新编译,导航到报告,它加载正常。我离开了,现在我得到一个弹出窗口,上面写着“对象引用未设置为对象的实例。”我点击了确定,弹出窗口消失了,我的程序继续运行,没有任何明显的问题。我可以导航回报告没有任何麻烦,但是每次我离开时都会显示此弹出窗口。

我无法调试弹出窗口的来源,因为如果我删除所有者,它会被查看者无法找到所有者以显示错误所吞噬。

对不起,冗长的描述。该项目非常大,因此尝试拟合源代码将比描述它占用更多的空间。如果您想查看我的代码的任何特定部分,只需发表评论,我会更新我的问题。

4

1 回答 1

1

我尝试了一堆不同的断点,并且能够将其缩小到我附加的依赖属性以绑定到 ViewerCore.ReportSource。当我更改为不同的视图时,此属性意外设置为 null,并且附加的属性没有考虑到这一点。如果将来有人遇到类似问题,您可以使用以下方法:

public static class DependencyPropertyHost
{
    public static readonly DependencyProperty ReportSourceProperty = DependencyProperty.RegisterAttached("ReportSource", typeof(ReportDocument), typeof(DependencyPropertyHost), new PropertyMetadata(ReportSourceChanged));

    public static ReportDocument GetReportSource(DependencyObject obj)
    {
        return obj.GetValue(ReportSourceProperty) as ReportDocument;
    }

    public static void SetReportSource(DependencyObject obj, ReportDocument value)
    {
        obj.SetValue(ReportSourceProperty, value);
    }

    private static void ReportSourceChanged(object sender, DependencyPropertyChangedEventArgs args)
    {
        var viewer = sender as CrystalReportsViewer;
        if (viewer != null && args.NewValue != null)
        {
            viewer.ViewerCore.ReportSource = args.NewValue;
        }
    }
}
于 2013-01-03T17:30:00.393 回答