Я недавно смотрел Шаблоны обслуживания Джона Папы с SL из SL Firestarter 2010 , в которых описан шаблон сервиса в MVVM Light, который я сейчас пытаюсь реализовать. Я опишу процесс ниже, но хотел бы сначала заявить, что я смог получить данные «времени разработки» без проблем. То, что я не могу понять, это мои данные во время выполнения. К сожалению, мой клиент застрял с помощью веб-служб .asmx старой школы, и мои руки связаны с этим.
Из моей ViewModel я вызываю IAccountService, интерфейс, который я настроил с помощью моего единственного метода: GetAccounts. Отсюда я использую класс ServiceProviderBase, чтобы определить, поступил ли вызов во время разработки или во время выполнения. Когда я вызываю этот метод во время разработки, я загружаю DesignAccountService, который использует модель DesignAccount для заполнения поддельных данных, которые в конечном итоге отображаются в моем Gridview. Это работает, я в восторге.
Когда я вызываю метод GetAccounts из среды выполнения,. Парень из БД здесь написал и протестировал веб-сервис, который возвращает данные в таблицу данных, а затем преобразует их в ObservableCollection. Этот веб-сервис работает внутри веб-проекта решения. Я пытаюсь вызвать этот веб-сервис из моего проекта SL и получить наблюдаемую коллекцию ... Хорошо, так что код:
В моей ViewModel:
protected TSMVVM.Services.IAccountService AccountService { get; set; }
public AccountDefinitionViewModel(TSMVVM.Services.IAccountService accountService)
{
AccountService = accountService;
LoadData();
}
public void LoadData()
{
LoadAccounts();
}
public void LoadAccounts()
{
Accounts = null;
AccountService.GetAccounts(GetAccountsCallback);
}
private void GetAccountsCallback(ObservableCollection<TSMVVM.Model.P.P_ACCOUNTS> accounts)
{
if (accounts != null)
{
this._accounts = accounts;
if (_accounts.Count > 0)
{
SelectedAccount = Accounts[0];
}
}
}
private ObservableCollection<TSMVVM.Model.P.P_ACCOUNTS> _accounts;
public ObservableCollection<TSMVVM.Model.P.P_ACCOUNTS> Accounts
{
get { return _accounts; }
set
{
_accounts = value;
RaisePropertyChanged("Accounts");
}
}
Интерфейс:
public interface IAccountService
{
void GetAccounts(Action<ObservableCollection<TSMVVM.Model.P.P_ACCOUNTS>> getAccountsCallback);
}
AccountService
private ObservableCollection<TSMVVMCommonSVC.TSAccount> _account = new ObservableCollection<TSMVVMCommonSVC.TSAccount>();
private TSMVVMCommonSVC.CommonSoapClient CommonService;
private Action<ObservableCollection<TSMVVMCommonSVC.TSAccount>> _getAccountsCallback;
public AccountService()
{
}
public void GetAccounts(Action<ObservableCollection<TSMVVM.Model.P.P_ACCOUNTS>> getAccountsCallback)
{
_getAccountsCallback = getAccountsCallback;
Uri iSilverlightServiceUriRelative = new Uri(App.Current.Host.Source, "../Services/Common.asmx");
EndpointAddress iSilverlightServiceEndpoint = new EndpointAddress(iSilverlightServiceUriRelative);
BasicHttpBinding iSilverlightServiceBinding = new BasicHttpBinding(BasicHttpSecurityMode.Transport);// Transport if it's HTTPS://
CommonService = new TSMVVMCommonSVC.CommonSoapClient(iSilverlightServiceBinding, iSilverlightServiceEndpoint);
CommonService.GetAccountCollectionCompleted +=new EventHandler<TSMVVMCommonSVC.GetAccountCollectionCompletedEventArgs>(CommonService_GetAccountCollectionCompleted);
CommonService.GetAccountCollectionAsync();
}
private void CommonService_GetAccountCollectionCompleted(object sender,TSMVVMCommonSVC.GetAccountCollectionCompletedEventArgs e)
{
if (e.Result.Length > 0)
{
foreach (TSMVVMCommonSVC.TSAccount item in e.Result) {
var acct = new TSMVVM.Model.P.P_ACCOUNTS() {
ACCOUNT_NUMBER = item.AccountNumber,
DESCRIPTION = item.AccountDescription
};
_account.Add(acct);
}
}
_getAccountsCallback(_account);
}
Теперь, если я поставлю точку останова в моей ViewModel на GET для учетных записей (которая должна возвращать _accounts), для учетных записей будет настроена коллекция элементов с 315 элементами в ней. Если я углублюсь в эту коллекцию, то увижу, что данные успешно возвращены из моего веб-сервиса. Фактически, в этот момент останова, если я вхожу в свой xaml (код работает практически одинаково в DataGrid вместо элемента управления telerik),
<telerik:RadGridView ItemsSource="{Binding Accounts}"
SelectedItem="{Binding SelectedAccount, Mode=TwoWay}"
AutoGenerateColumns="False">
<telerik:RadGridView.Columns>
<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=ACCOUNT_NUMBER}" Header="Account Number" />
<telerik:GridViewDataColumn DataMemberBinding="{Binding Path=DESCRIPTION}" Header="Description" />
</telerik:RadGridView.Columns>
</telerik:RadGridView>
С установленной точкой останова я вижу, что переменная Accounts в моей привязке ItemsSource установлена на эту коллекцию из 315 элементов. Однако сетка пуста. Я знаю, что мои привязки столбцов привязаны к правильным элементам, но я не могу понять, куда идти дальше.