ObjectDataProvider en MVVM pas nécessaire?
-
01-10-2019 - |
Question
J'ai créé un MVVM simple, avec seulement trois classes CashFlowView, CashFlowViewModel, CashFlowModel.
J'utilise 9.1 XamDataPresenter d'un infragistic (ou xamDataGrid).
<igDP:XamDataPresenter Name="xamDataPresenter1" DataSource="{Binding Source={StaticResource CashFlowData}}">
<ObjectDataProvider x:Key="CashFlowData" ObjectType="{x:Type ViewModel:CashflowViewModel}" MethodName="GetCashFlows" />
Dans mon ViewModel:
public ObservableCollection<CashflowModel> GetCashFlows()
{
return new ObservableCollection<CashflowModel>() { ... };
}
ViewModel est connecté à la vue par ceci:
this.DataContext = new CashflowViewModel();
Tant que je connecte la grille au ObjectDataProvider son parfaitement fonctionne bien. Mais je voulais que je pouvais connecter à une propriété dans mon ViewModel à la place.
Selon Infragistics tout ce que je dois faire est la suivante:
<igDP:XamDataGrid DataSource="{Binding Path=ViewModelCollection}"/>
Mais dans ce cas, il semble que je dois lier à une collection d'une autre ViewModel pour représenter mes lignes à l'intérieur de la grille. Et c'est là où je suis confus.
J'ai essayé et cela ne fonctionne pas:
<igDP:XamDataPresenter Name="xamDataPresenter1" DataSource="{Binding Path=CashFlows}">
A l'intérieur du ViewModel:
public ObservableCollection<CashflowDataGridViewModel> CashFlows
{
get
{
return new ObservableCollection<CashflowDataGridViewModel>();
}
}
Mais comment puis-je créer mon deuxième ViewModel (CashflowDataGridViewModel)?
J'ai essayé d'ajouter ce proprty dans ce deuxième ViewModel:
public CashflowModel CashFlow
{
get
{
return new CashflowModel() {...};
}
}
Mais tout ce que je me montré sur mon avis est en-tête de colonne « Cashflow » sans les en-têtes sous-jacentes de la classe cashflowModel réelle.
La solution
Pour pouvoir lier la vue à des propriétés du ViewModel, DataContext doit être définie à une instance de votre ViewModel. Ce que je fais habituellement est d'inclure la ligne suivante dans le constructeur du code-behind pour mon point de vue:
this.DataContext = new SomeAwesomeViewModel();
Vous pouvez également définir la DataContext pour les conteneurs si vous voulez différents groupes de contrôles à utiliser différents ViewModels (par exemple, Grid.DataContext, StackPanel.DataContext, etc.).
Une fois que vous avez l'ensemble DataContext, vous devriez être capable de se lier aux propriétés de cette ViewModel.
Mise à jour
Voici un peu de code échantillon pour vous permettre de continuer.
public class CashFlowViewModel
{
public ObservableCollection<FlowViewModel> DataGridData
{
get...
}
}
C'est la propriété qui devrait fournir les données pour le DataGrid. Maintenant, voici ce que la classe FlowViewModel
pourrait ressembler.
public class FlowViewModel
{
decimal flowAmount;
public decimal FlowAmount
{
get { return flowAmount; }
set
{
if(flowAmount == value)
return;
flowAmount = value;
NotifyPropertyChanged("FlowAmount");
}
}
.
.
.
private void NotifyPropertyChanged(string propertyName)
{
if(PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}