2009-08-18 2 views
1

У меня есть первый WPF работает нормально с ObjectDataProvider в 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 не найден».

Итак, что я делаю неправильно в ссылке на это и/или как кто-то другой выполнит эту привязку данных, чтобы я мог на самом деле ловушку для ошибок подключения и отвлечь основную форму к удобной для пользователя форме ошибки?

СПАСИБО!

+0

+ 1 - ODS и SQL Params в разметке всегда заставляли меня чувствовать себя менее свежей. Я успешно сделал ReportDataSourses полностью в коде, но никогда не получал этот неуловимый ODS для работы. –

ответ

2

Я бы переместил логику доступа к данным в отдельную службу и, возможно, в свою собственную сборку полностью, чтобы обеспечить ваше намеренное разделение проблем. Тогда у меня будет модель просмотра, использующая указанную службу для извлечения данных и отображения ее для представления. Тогда представление просто привязывается к модели представления и не заботится о том, поступают ли данные из базы данных или что-то еще.

Я бы посоветовал ознакомиться с разделом проблем, инсталляции локатора/зависимостей службы и MVVM.

+0

Жаль, что у меня было время, брат, жаль, что у меня не было времени! ;) – LSTayon

+0

Ну, кто бы ни наследовал ваш код, тот захочет то же самое;) –

2

Вы получаете эту ошибку, потому что 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 само-освежающий, убедитесь, что он реализует INotifyPropertyChanged или INotifyCollectionChanged в соответствующий для того, чтобы обязательные целевые обновления при изменении данных.

Смежные вопросы