如何不使用 ObjectDataProvider?
我的第一个 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您收到该错误是因为
oPatients
不是StaticResource
。 它必须按照ObjectDataProvider
的方式在ResourceDictionary
中定义,但作为类成员则不然。 您可以将其公开为公共财产:然后直接绑定到它:
假设我没有犯一些愚蠢的错误,那应该可行。 但是,它仍然不能解决您的问题,因为您正在构造函数中加载数据,这意味着任何异常都会导致
clsPatients
构造失败,进而导致MainWindow< /code> 构造失败,您无法正确处理它,因为它是堆栈跟踪旁边的老鼠,与合法的构造失败无法区分。
Kent 100%正确:数据应该来自外部提供商。
您可能有资源限制,但即使您无法实现分层架构,您仍然可以建立良好的设计。 至少,通过将数据加载到单独的数据提供程序类中,然后将完整形成的数据传递到窗口中来建立关注点分离。 这使您可以隔离发生故障的位置,并使代码保持更松散的耦合。
并将其调用为:
此外,如果 clsPatients 是自刷新的,请确保它根据需要实现
INotifyPropertyChanged
或INotifyCollectionChanged
以便绑定目标当数据改变时更新。You're getting that error because
oPatients
is not aStaticResource
. It would have to be defined in theResourceDictionary
the way yourObjectDataProvider
was, but as a class member it is not. You could expose it as a public property:Then bind to it directly:
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 causeMainWindow
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.
and invoke it as:
Also, if
clsPatients
is self-refreshing, make sure it implementsINotifyPropertyChanged
orINotifyCollectionChanged
as appropriate in order for the binding targets to update when the data changes.我会将数据访问逻辑移至单独的服务中,甚至可能完全移至其自己的程序集中,以强制执行您预期的关注点分离。 然后我有一个视图模型使用所述服务来检索数据并将其公开给视图。 然后视图将简单地绑定到视图模型,而不会关心数据是否来自数据库或其他什么。
我建议阅读关注点分离、服务定位器/依赖注入和 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.