Ok, j'enlève mes cheveux, donc toute aide sera grandement appréciée!Impossible de créer une base de données au moment de la conception dans WPF à l'aide de MVVM - La propriété ViewModel ne s'appelle jamais
Je construis une application WPF en utilisant le modèle MVVM.
Pour tenter d'obtenir des données dans au moment de la conception J'utilise le cadre de l'injection de dépendance Ninject en liaison avec un localisateur de services (un peu comme l'exemple dans un article (au http://jonas.follesoe.no/YouCardRevisitedImplementingDependencyInjectionInSilverlight.aspx
J'utilise WPF et pas Silverlight je vérifie les propriétés de temps de conception légèrement différemment, mais sinon je crois qu'il est applicable.)
Je ne peux pas le faire fonctionner au moment du design, peu importe ce que je fais la liaison ne semble même pas appelé Cela fonctionne bien à l'exécution
Voici le code pour mon module Ninject:
public class ViewModelModule : StandardModule
{
public override void Load()
{
bool isRuntime = !ViewModelBase.IsInDesignMode;
if (isRuntime)
{
Bind<IViewModel>().To<MyViewModel>();
}
else
{
Bind<IViewModel>().To<MyDesignTimeViewModel>();
}
}
}
MyDesignTimeViewModel
est un objet CLR simple qui renvoie des données codées en dur à la place de toutes les mêmes propriétés sur MyViewModel
.
Le service de localisation est la suivante:
public class ViewModelLocator
{
private static IKernel kernel;
static ViewModelLocator()
{
if (kernel == null)
{
kernel = new StandardKernel(new ViewModelModule());
}
}
public IViewModel ViewModel
{
get
{
var vm = kernel.Get<IViewModel>();
return vm;
}
}
}
Et le XAML lie le DataContext de la page comme suit (bien que je l'ai essayé quelques différentes façons de le déclarer, tous avec le même résultat):
<Page.DataContext>
<Binding Source="{StaticResource viewModelLocator}" Path="ViewModel" />
</Page.DataContext>
(où le viewModelLocator est déclaré dans un ResourceDictionary qui est fusionné au sommet de ce fichier). Comme je l'ai dit, cela fonctionne très bien à l'exécution, même si je change ma liaison Ninject pour utiliser MyDesignTimeViewModel lors de l'exécution, elle affiche correctement les données fictives. J'ai un convertisseur fictif dans une de mes liaisons pour voir ce qui est passé et cela est appelé au moment de l'exécution, mais pas au moment du design (j'ai débogué frénétiquement une instance de conception en utilisant un processus Visual Studio séparé toute la journée, par les recommandations MSDN!)
Au moment du design, la liaison Ninject se poursuit, ainsi que l'instanciation du noyau. Ensuite, viewModel est appelé et renvoie un DesignTimeViewModel, avec toutes mes données codées en dur. Mais la liaison réelle à l'une des propriétés sur le viewmodel ne semble jamais être appelée (le point d'arrêt du convertisseur fictif n'est jamais touché).
Je ne peux vraiment pas voir ce que je fais mal. Tout pointeur dans n'importe quelle direction serait grandement apprécié car à ce stade, je suis juste déconcerté. Merci :)
Ok, une mise à jour: Cela doit être en rapport avec le fonctionnement de Visual Studio WPF Designer par rapport au concepteur Expression Blend. Il s'avère que cela fonctionne comme prévu dans Blend (ie DesignViewModel est instancié au moment du design, tandis que le ViewModel 'normal' fonctionne comme d'habitude à l'exécution) mais pas dans Visual Studio (bien que je voulais Blend quand même!) . Peut-être que quelqu'un ayant plus de connaissances sur les concepteurs de WPF peut venir et expliquer ?! En attendant, je vais accepter cette réponse car ce sont tous d'excellents conseils, mais je ne vois rien qui explique que cela ne fonctionne pas dans le concepteur VS2008. – randomsequence
Lorsque vous parliez de concepteur de débogage, vous avez parlé de Blend ou de Visual Studio? Comment calculez-vous ViewModelBase.IsInDesignMode? – Anvaka
Ma question initiale était dans Visual Studio (je n'avais pas ouvert Blend jusqu'à ce matin car je supposais qu'ils travaillaient de manière similaire au moment du design). ViewModelBase.IsInDesignMode examine DesignerProperties.IsInDesignModeProperty en mode WPF et HtmlPage.IsEnabled en mode Silverlight (il s'agit de WPF). Je suis sûr qu'il détecte correctement le mode de conception. – randomsequence