我最近观看了John Papa的Service Patterns with SL from SL Firestarter 2010,它描述了MVVM Light中的一个服务模式,我正在尝试实现它。我将描述下面的过程,但首先要说明的是,我已经能够让我的“设计时间”数据毫无问题地工作。我无法弄清楚的是我的运行时数据。不幸的是,我的客户使用老派的.asmx网络服务卡住了,我的双手被绑在这一块上。MVVM Web服务数据在设计时间和运行时间
在我的ViewModel中,我调用了IAccountService,这是我用一个方法设置的接口:GetAccounts。从这里,我使用ServiceProviderBase类来确定调用是来自designtime还是runtime。当我从设计时调用此方法时,我加载了一个DesignAccountService,它使用DesignAccount Model来填充假数据,最终显示在我的Gridview中。它有效,我很兴奋。
当我从运行时调用GetAccounts方法时,。这里的数据库人员编写并测试了一个将数据返回到数据表的Web服务,然后将其转换为ObservableCollection。此Web服务正在解决方案的Web项目中运行。我试图调用从我的SL项目该Web服务&抢观察集合......好了,所以代码:
在我的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);
}
现在,如果我在我的Vie中放置了一个断点wModel在GET帐户(设置为返回_accounts),帐户被设置为包含315项的项目集合。如果我深入了解该集合,我可以看到数据从我的Web服务成功返回。事实上,在此断点,如果我一头扎进我的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>
具有断点设置,我可以看到帐户变量,在我ItemsSource绑定,设置为315个项目的集合。但是,网格是空的。我知道我的列绑定绑定到正确的项目,但我无法弄清楚从哪里去。
你可以向我们展示代码,在哪里将View和ViewModel绑定在一起? – Euphoric 2011-02-01 06:14:48
就像更多的FYI一样 - 我使用ViewModelLocator,它是MVVMLight工具包的一部分。由于我的设计时间数据正在工作,这绝对具有约束力。 – 2011-02-01 19:17:01