如何不使用 ObjectDataProvider?

发布于 2024-08-02 00:23:47 字数 980 浏览 5 评论 0原文

我的第一个 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” 。

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

谢谢!

I have my first WPF working fine with an ObjectDataProvider in the XAML:

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

However, I don't like using this because if there is a connection error, I can't trap it and the program just barfs out.

So, what I've been trying to do is to instantiate the collection object directly in the codebehind...

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

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

...and then reference it in my databinding as so:

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

But, I'm getting "local:oPatients was not found".

So...what am I doing wrong in referencing this and/or how would someone else accomplish this data binding so that I can actually trap for connection errors and divert the main form to a user-friendly error form?

THANKS!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

风情万种。 2024-08-09 00:23:47

您收到该错误是因为 oPatients 不是 StaticResource。 它必须按照 ObjectDataProvider 的方式在 ResourceDictionary 中定义,但作为类成员则不然。 您可以将其公开为公共财产:

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< /code> 构造失败,您无法正确处理它,因为它是堆栈跟踪旁边的老鼠,与合法的构造失败无法区分。

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 以便绑定目标当数据改变时更新。

You're getting that error because oPatients is not a StaticResource. It would have to be defined in the ResourceDictionary the way your ObjectDataProvider was, but as a class member it is not. You could expose it as a public property:

public clsPatients Patients { get; set; }

Then bind to it directly:

<!-- 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}">

Assuming I haven't made some stupid mistake, that should work. However, it still doesn't solve your problem because you're loading the data in the constructor, which means that any exceptions will cause clsPatients construction to fail, which in turn will cause MainWindow construction to fail, which you cannot properly handle because it's a rats next of a stack trace that's indistinguishable from a legitimate construction failure.

Kent is 100% right: The data should come from an external provider.

You may have resource limitations, but you can still establish good design even if you can't implement a tiered architecture. At bare minimum, establish separation of concerns by loading the data in a separate data provider class then passing the fully-formed data into the window. That allows you to isolate failures where they occur, and keep your code somewhat more loosely coupled.

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
    }
}

and invoke it as:

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);
}

Also, if clsPatients is self-refreshing, make sure it implements INotifyPropertyChanged or INotifyCollectionChanged as appropriate in order for the binding targets to update when the data changes.

甜中书 2024-08-09 00:23:47

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

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

I'd move the data access logic into a separate service, and perhaps into its own assembly entirely to enforce your intended separation of concerns. Then I'd have a view model use said service to retrieve data and expose it for the view. Then the view would simply bind to the view model and wouldn't care whether the data came from a database or whatever.

I would suggest reading up on separation of concerns, service locator/dependency injection, and MVVM.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文