web-dev-qa-db-fra.com

Quelles sont les approches disponibles pour les données factices au moment de la conception dans WPF?

Je travaille sans mélange d'expression et j'utilise simplement l'éditeur XAML dans vs2010. Mis à part la sagesse de cela, je constate de plus en plus un besoin de liaison de données au moment de la conception. Pour les cas simples, la propriété FallbackValue fonctionne très bien (Textboxes et TextBlocks, etc.). Mais surtout quand il s'agit de ItemsControl et similaires, il faut vraiment que les exemples de données soient visibles dans le concepteur pour que vous puissiez ajuster et ajuster les contrôles et les modèles de données sans avoir à exécuter l'exécutable.

Je sais que ObjectDataProvider permet de se lier à un type, et peut donc fournir des données au moment de la conception pour la visualisation, mais il y a un peu de jonglage pour permettre aux vraies données d'exécution de se lier sans gaspiller les ressources en chargeant chargement à la fois de la conception, des données factices et des liaisons d'exécution.

Vraiment, ce que je veux, c'est la possibilité d'avoir, disons, "John", "Paul", "George" et "Ringo" apparaissent dans le concepteur XAML en tant qu'éléments stylables dans mon ItemsControl, mais ont de vrais les données s'affichent lors de l'exécution de l'application.

Je sais également que Blend permet certains attributs fantaisistes qui définissent les données de liaison au moment de la conception qui sont effectivement ignorées par WPF dans les conditions d'exécution.

Mes questions sont donc:

1. Comment puis-je tirer parti des liaisons au moment du design des collections et des données non triviales dans le concepteur XAML de Visual Studio, puis passer aux liaisons d'exécution en douceur?

2. Comment d'autres ont-ils résolu ce problème de données au moment de la conception par rapport à l'exécution? Dans mon cas, je ne peux pas très facilement utiliser les mêmes données pour les deux (comme on pourrait le faire, disons, avec une base de données question).

. Est-ce que leurs alternatives au mélange d'expressions que je pourrais utiliser pour la conception XAML intégrée aux données? (Je sais qu'il existe des alternatives, mais je veux spécifiquement quelque chose que je puisse utiliser et voir des exemples de données liées, etc.? )

95
el2iot2

En utilisant VS2010, vous pouvez utiliser Attributs au moment du design (fonctionne pour SL et WPF). J'ai généralement une fausse source de données, donc c'est juste une question de:

  • Ajout de la déclaration d'espace de noms

    xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"
    
  • Ajout du contexte de données factices aux ressources de fenêtre/contrôle

    <UserControl.Resources>
      <ViewModels:MockXViewModel x:Key="DesignViewModel"/>
    </UserControl.Resources>
    
  • Définition du contexte des données au moment du design

    <Grid d:DataContext="{Binding Source={StaticResource DesignViewModel}}" ...
    

Fonctionne assez bien.

119
Goran

Comme un amalgame de la réponse acceptée de Goran et de l'excellent commentaire de René.

  • Ajoutez la déclaration d'espace de noms. xmlns:d="http://schemas.Microsoft.com/expression/blend/2008"

  • Référencez votre contexte de données de conception à partir du code.
    <Grid d:DataContext="{d:DesignInstance Type=ViewModels:MockXViewModel, IsDesignTimeCreatable=True}" ...

11

Karl Shifflett décrit une approche qui devrait fonctionner aussi bien pour VS2008 que VS2010:

Affichage des données de conception dans Visual Studio 2008 Cider Designer dans les projets WPF et Silverlight

Laurent Bugnion a une approche similaire qui se concentre sur Expression Blend. Cela pourrait fonctionner pour VS2010, mais je ne l'ai pas encore confirmé.

Simulation de données en mode conception dans Microsoft Expression Blend

4
dthrasher

J'utilise cette approche pour générer des données de conception avec .NET 4.5 et Visual Studio 2013.

Je n'ai qu'un seul ViewModel. Le modèle de vue a une propriété IsInDesignMode qui indique si le mode de conception est actif ou non (voir classe ViewModelBase). Vous pouvez ensuite configurer vos données de conception (comme remplir un contrôle d'éléments) dans le constructeur de modèles de vue.

En outre, je ne chargerais pas de données réelles dans le constructeur de modèles de vue, cela peut entraîner des problèmes lors de l'exécution, mais la configuration des données pour la conception ne devrait pas être un problème.

public abstract class ViewModelBase
{
    public bool IsInDesignMode
    {
        get
        {
            return DesignerProperties.GetIsInDesignMode(new DependencyObject());
        }
    }
}

public class ExampleViewModel : ViewModelBase
{
    public ExampleViewModel()
    {
        if (IsInDesignMode == true)
        {
            LoadDesignTimeData();
        }
    }

    private void LoadDesignTimeData()
    {
        // Load design time data here
    }       
}
4
Martin

Peut-être que les nouvelles fonctionnalités de Visual Studio 2010 et Expression Blend 4 sont une option pour vous.

Son fonctionnement est indiqué dans l'exemple d'application BookLibrary de WPF Application Framework (WAF). Veuillez télécharger la version .NET4.

4
jbe

En utilisant Visual Studio 2017, j'ai essayé de suivre tous les guides et questions comme celui-ci et j'étais toujours confronté à un <ItemsControl> qui n'a tout simplement pas exécuté le code que j'avais à l'intérieur du constructeur d'un DesignFooViewModel qui hérite de FooViewModel. J'ai confirmé la partie "n'a pas exécuté" après cela guide MSDN "pratique" (spoiler: MessageBox débogage). Bien que cela ne soit pas directement lié à la question d'origine, j'espère que cela fera gagner beaucoup de temps aux autres.

Il s'avère que je ne faisais rien de mal. Le problème était que mon application devait être construite pour x64. Comme le Visual Studio est toujours en 2018 un processus 32 bits et ne peut apparemment pas faire tourner un processus hôte 64 bits pour la partie designer, il ne peut pas utiliser mes classes x64. La chose vraiment mauvaise est qu'il n'y a aucune erreur dans aucun journal auquel je puisse penser.

Donc, si vous tombez sur cette question parce que vous voyez des données fausses dans votre modèle de vue de conception (par exemple: <TextBlock Text="{Binding Name}"/> s'affiche Name peu importe la définition de la propriété), la cause est probablement votre build x64. Si vous ne parvenez pas à modifier votre configuration de build en anycpu ou x86 en raison de dépendances, envisagez de créer un nouveau projet qui est entièrement anycpu et ne possède pas les dépendances (ou les dépendances). Vous finissez donc par diviser la plupart ou la totalité, sauf les parties d'initialisation du code, de votre projet "WPF App" en un projet "Bibliothèque de classes C #".

Pour la base de code sur laquelle je travaille, je pense que cela forcera une séparation saine des préoccupations au prix d'une certaine duplication de code, ce qui est probablement une chose positive.

3
joonas

Similaire à la réponse la mieux notée, mais mieux à mon avis: vous pouvez créer une propriété statique pour renvoyer une instance de données de conception et la référencer directement à partir de XAML comme suit:

<d:UserControl.DataContext>
    <Binding Source="{x:Static designTimeNamespace:DesignTimeViewModels.MyViewModel}" />
</d:UserControl.DataContext>

Cela évite d'avoir à utiliser UserControl.Resources. Votre propriété statique peut fonctionner comme une fabrique vous permettant de construire des types de données non triviaux - par exemple, si vous n'avez pas de ctor par défaut, vous pouvez appeler une fabrique ou un conteneur ici pour injecter les dépendances appropriées.

1
Schneider