2009-09-19 3 views
15

J'ai un datatemplate pour un modèle de vue où un itemscontrol est lié à un CollectionViewSource (pour activer le tri dans xaml).Les données DesignTime ne s'affichent pas dans Blend lorsqu'elles sont liées à CollectionViewSource

<DataTemplate x:Key="equipmentDataTemplate"> 
    <Viewbox> 
     <Viewbox.Resources> 
      <CollectionViewSource x:Key="viewSource" Source="{Binding Modules}"> 
       <CollectionViewSource.SortDescriptions> 
        <scm:SortDescription PropertyName="ID" Direction="Ascending"/> 
       </CollectionViewSource.SortDescriptions> 
      </CollectionViewSource> 
     </Viewbox.Resources> 
     <ItemsControl ItemsSource="{Binding Source={StaticResource viewSource}}" 
         Height="{DynamicResource equipmentHeight}" 
         ItemTemplate="{StaticResource moduleDataTemplate}"> 
      <ItemsControl.ItemsPanel> 
       <ItemsPanelTemplate> 
        <StackPanel Orientation="Horizontal" /> 
       </ItemsPanelTemplate> 
      </ItemsControl.ItemsPanel> 
     </ItemsControl> 
    </Viewbox> 
</DataTemplate> 

J'ai installé aussi le UserControl où tout cela est défini pour fournir des données DesignTime

d:DataContext="{x:Static vm:DesignTimeHelper.Equipment}"> 

Ceci est essentiellement une propriété statique qui me donne un EquipmentViewModel qui a une liste de ModuleViewModels (équipement. Modules). Maintenant, tant que je lie au CollectionViewSource les données de designtime ne se présente pas dans le mélange 3. Quand je lie à la collection ViewModel directement

<ItemsControl ItemsSource="{Binding Modules}" 

Je peux voir les données DesignTime. Une idée de ce que je pourrais faire?

+2

Avoir exactement le même problème. Liaison contre une propriété List est très bien, mais dès que je lie à un CollectionView lié à cette propriété, toutes les données disparaissent. –

Répondre

7

là fait que (maintenant au moins) :)

C'est la solution que j'ai trouvé. L'astuce consiste à remplacer la source pour le designtime de CollectionViewSource. J'utilise la propriété d:DesignSource utiliser un autre designtime de ressource statique:

<Window.Resource> 
    <CollectionViewSource x:Key="ViewSource" 
      Source="{Binding ModelProperty}" 
      d:DesignSource="{{x:Static MyProg:DesignTimeData.MyList}"> 
     <!-- Contents --> 
    </CollectionViewSource> 
</Window.Resources> 

<!-- No change to the using class --> 
<ListBox ItemsSource="{Binding Source={StaticResource ViewSource}}"> 

</ListBox> 
0
  1. Je ne suis pas sûr x:Static est censé travailler dans d:DataContext, je pense que d: DesignInstance ou d:DesignData pourrait.
  2. Avez-vous testé les données de conception et assurez-vous que les données sont bien remplies?
  3. Essayez de spécifier la propriété d:IsDesignTimeCreatable=True dans le d:DesignInstance.
  4. Bien que this est Silverlight spécifique, je suis sûr qu'il pourrait vous donner un indice.

Il devrait ressembler généralement comme ceci:

d:DataContext="{d:DesignInstance Type=vm:EquipmentViewModel, IsDesignTimeCreatable=True}"

Vous pouvez utiliser le même ViewModel pour les temps d'exécution et designtime, faire une propriété IsInDesignTime en vous ViewModelBase et renvoyer des données de façon appropriée.
Exemple:

private static bool? _isInDesignMode; 
public static bool IsInDesignModeStatic 
{ 
    get 
    { 
     if (!_isInDesignMode.HasValue) 
     { 
      var prop = DesignerProperties.IsInDesignModeProperty; 
      _isInDesignMode 
       = (bool)DependencyPropertyDescriptor 
       .FromProperty(prop, typeof(FrameworkElement)) 
       .Metadata.DefaultValue; 
     } 

     return _isInDesignMode.Value; 
    } 
} 

Note: Je vous encourage à utiliser StaticResources (plutôt que DynamicResources) pour les modèles ou les styles qui ne sont pas destinés à changer lors de l'exécution. Lisez this pour plus d'informations.

0

Je ne sais pas si cela est toujours d'actualité ... avait récemment un problème similaire - je suis toujours quelque part sur la courbe d'apprentissage WPF, tout simplement pas tout à fait sûr où ...

De toute façon, voici le scénario: Je voudrais créer un objet de type ObservableCollection quelque part dans mon espace de noms local (pour garder les choses simples), par exemple ..

public class NodesCollection : ObservableCollection<Nodes> { }

Puis de Blend/XAML, je peux facilement « Créer un objet source de données » (à partir du panneau d'outils de données) et trouver NodesCollection est représentée et peut être sélectionné.

Ensuite, Blend va créer une ressource locale près du sommet du fichier XAML, semblable à:

<local:NodesCollection x:Key="NodesCollectionDataSource" d:IsDataSource="True" />

Avec cela, vous pouvez facilement lier la propriété ItemsSource d'une zone de liste à la source de données que nous avons vient de créer. Par exemple, cliquez avec le bouton droit sur votre zone de liste dans le panneau d'outils "Objets et chronologie" et sélectionnez "Lier les données à la source de données". Dans la boîte de dialogue contextuelle, vous verrez NodesCollectionDataSource est disponible et peut être utilisé.

Mais ici vient les questions que je devais résoudre ...

Dans certains livres que je lis en ce moment, ils parlent de la création d'un CollectionViewSource en XAML qui peut être utilisé pour le tri/regroupement/Filtrage/navigation de la source de données sous-jacente.

Premier problème, je ne trouve CollectionViewSource nulle part dans Blend; La seule option est donc de créer manuellement le tag dans Xaml.

Tapez simplement <CollectionViewSource x:Key="cvsNodes" /> dans le bloc Ressources (Xaml) et à partir de là, vous pouvez modifier des propriétés supplémentaires à l'aide de l'interface graphique de Blend; par exemple, définition de la propriété Source sous-jacente et des descripteurs de tri et de groupe supplémentaires (situés dans le panneau Outils Ressources).

Maintenant vient la partie où nous voulons lier la propriété ItemsSource de ListBox à CollectionViewSource. Cependant, vous ne serez pas en mesure de trouver cet élément en utilisant l'interface graphique Blend. Par conséquent, vous devez taper la valeur de liaison manuellement. Par exemple:

<ListBox x:Name=.. ItemsSource="{Binding Source={DynamicResource cvsNodes}}".. />

Cela fonctionne. Mais pour le rendre encore plus facile, nous devons revenir à l'élément de ressource CollectionViewSource originale en XAML et ajouter un attribut supplémentaire:

<CollectionViewSource x:Key="cvsNodes" Source=... d:IsDataSource="True"

Le d:IsDataSource="True" fait le tour d'avoir GUI Blend reconnaître cette ressource comme disponible pour être utilisé.

Maintenant, si nous revenons à la propriété ItemsSource de la ListBox à partir du panneau d'outils Propriétés, nous devrions être en mesure de sélectionner cvsNodes dans la liste des sources de données disponibles. J'espère que cela aidera tous ceux qui sont parvenus à la même conclusion que moi, à savoir que Blend et la technologie Xaml sous-jacente ne sont pas complètement synchronisés; et que Blend est au mieux un outil pour générer le Xaml, pas un remplacement pour apprendre le langage Xaml.

+0

Aussi juste pour vous aider à répondre à la question originale; Oui, cela permet à Blend d'afficher des exemples de données pendant le développement. Tout ce que vous avez à faire est de remplir quelques exemples de données dans le constructeur de votre classe ObjectCollection - dans mon cas, ce serait le ctor de NodesCollection – klee

Questions connexes