1

我的第一个 WPF 与 XAML 中的 ObjectDataProvider 一起正常工作:

<ObjectDataProvider x:Key="WaitingPatientDS" ObjectType="{x:Type local:clsPatients}">
    <ObjectDataProvider.ConstructorParameters>
        <sys:Boolean>True</sys:Boolean>
    </ObjectDataProvider.ConstructorParameters>
</ObjectDataProvider>

但是,我不喜欢使用它,因为如果出现连接错误,我无法捕获它,程序就会停止运行。

所以,我一直在尝试做的是直接在代码隐藏中实例化集合对象......

public partial class MainWindow : Window
{
  ListBox _activeListBox;
  clsPatients oPatients;

public MainWindow()
{
  oPatients = new clsPatients(true);

...然后在我的数据绑定中引用它:

<StackPanel x:Name="stkWaitingPatients" Width="300" Margin="0,0,0,-3"
   DataContext="{Binding Mode=OneWay, Source={StaticResource local:oPatients}}">

但是,我得到“local:oPatients was not found”。

那么......我在引用这个和/或其他人如何完成此数据绑定时做错了什么,以便我实际上可以捕获连接错误并将主表单转移到用户友好的错误表单?

谢谢!

4

2 回答 2

3

我会将数据访问逻辑移到一个单独的服务中,也许完全移到它自己的程序集中,以强制执行您预期的关注点分离。然后我将有一个视图模型使用所述服务来检索数据并将其公开给视图。然后视图将简单地绑定到视图模型,而不关心数据是否来自数据库或其他。

我建议阅读关注点分离、服务定位器/依赖注入和 MVVM。

于 2009-08-18T14:18:18.720 回答
3

您收到该错误是因为oPatients不是StaticResource. 它必须以ResourceDictionary您的方式定义ObjectDataProvider,但作为一个类成员,它不是。您可以将其公开为公共属性:

public clsPatients Patients { get; set; }

然后直接绑定到它:

<!-- MainWindowRoot is the x:Name of your Window element. -->
<StackPanel x:Name="stkWaitingPatients" Width="300" Margin="0,0,0,-3"
   DataContext="{Binding Patients, ElementName=MainWindowRoot, Mode=OneWay}">

假设我没有犯一些愚蠢的错误,那应该可行。但是,它仍然不能解决您的问题,因为您是在构造函数中加载数据,这意味着任何异常都会导致clsPatients构造失败,进而导致MainWindow构造失败,您无法正确处理,因为它是老鼠与合法构造失败无法区分的堆栈跟踪的下一个。

Kent 100% 正确:数据应该来自外部提供商。

您可能有资源限制,但即使您无法实现分层架构,您仍然可以建立良好的设计。至少,通过将数据加载到单独的数据提供者类中,然后将完整格式的数据传递到窗口中来建立关注点分离。这使您可以在发生故障的地方隔离故障,并使您的代码更加松散地耦合。

public class PatientDataProvider
{
    public PatientDataProvider(WhatItNeedsToConnect whatItNeedsToConnect) 
    { 
        // this doesn't connect because the constructor shouldn't fail because of a connection failure
    }
    public clsPatients GetPatientData(bool yesOrNo) 
    {
        // this can fail because of a connection error or some other data loading error
    }
}

并将其调用为:

PatientDataProvider provider = new PatientDataProvider(whatItNeedsToConnect);
clsPatients patients = null;
try { 
    patients = provider.GetPatientData(true); 
    MainWindow w = new MainWindow { Patients = patients; };
    w.Show();
}
catch (WhateverExceptionGetsThrownByProvider e) 
{ 
    MessageBox.Show("Could not load patients: " + e.Message);
}

此外,如果clsPatients是自刷新,请确保它实现INotifyPropertyChangedINotifyCollectionChanged酌情以使绑定目标在数据更改时更新。

于 2009-08-26T07:57:49.050 回答