2009-02-24 4 views
5

Impossible de trouver une réponse à celui-ci.WPF - Set DataTemplate pour les GridViewColumns ajoutés par programme

J'ai un contrôle ListView WPF qui peut contenir un nombre variable de colonnes. Par exemple, il peut afficher des données client, affichage des colonnes Id, Nom, Email etc, ou il peut contenir des produits, affichage ID, Nom, Prix, NumberInStock, Fabricant, bien, vous obtenez l'idée: nombre variable de colonnes, noms variables.

Ce que je veux faire, c'est que certaines colonnes affichent les données différemment. Par exemple, au lieu d'imprimer "Oui" ou "Non" comme valeur de la colonne NumberInStock, je souhaite afficher une image nette.

Si j'avais un nombre fixe de colonnes, avec des noms fixes à lier, je vois un peu comment c'est facile. Il suffit de définir un DataTemplate pour cette colonne particulière et je l'utiliserais pour définir la vue de ma colonne. Cependant, je ne peux pas voir comment le faire dans ma situation.

Je suis très nouveau sur WPF, alors excusez-moi si mon approche est mauvaise :-) Dans mon XAML, j'ai défini un contrôle ListView, qui est quasiment vide. Dans mon code derrière, je l'utilise:

// get all columns from my objects (which can be either a Customer of Product) 
    foreach (string columnName in MyObject.Columns) 
     { 
      GridViewColumn column = new GridViewColumn(); 
      // Bind to a property of my object 
      column.DisplayMemberBinding = new Binding("MyObject." + columnName); 
      column.Header = columnName; 
      column.Width = 50; 
      // If the columnname is number of stock, set the template to a specific datatemplate defined in XAML 
      if (columnName == "NumberInStock") 
      column.CellTemplate = (DataTemplate)FindResource("numberInStockImageTemplate"); 
      explorerGrid.Columns.Add(column); 
     } 

Ok, je suis sûr que cela pourrait se faire un peu plus joli (si vous avez des conseils, s'il vous plaît!), Mais le plus gros problème est que je ne vois pas différence dans la colonne. Il affiche simplement la valeur de texte de la colonne 'NumberInStock'. Mon DataTemplate est défini dans le XAML:

<Window.Resources> 
<DataTemplate x:Name="NumberInStock" x:Key="NumberInStock"> 
     <Border BorderBrush="Red" BorderThickness="2.0"> 
     <DockPanel> 
      <Image Width="24" Height="24" Margin="3,0" Source="..\Images\instock.png" /> 
     </DockPanel> 
     </Border> 
</DataTemplate> 
</Window.Resources> 

Bien sûr, je dois encore ajouter la fonctionnalité qu'il afficherait un « oui » ou « non » l'image en fonction de la valeur de NumberInStock, mais c'est pas 2 vraiment. Je serais heureux de voir une image et une bordure rouge dans ma ListView!

Merci à l'avance, Razzie

Répondre

7

Cela m'a fait trébucher pendant un moment.

DisplayMemberBinding et CellTemplate s'excluent mutuellement. La spécification d'un DisplayMemberBinding entraîne l'ignorance de CellTemplate.

De MSDN:

Les propriétés suivantes sont utilisées pour définir le contenu et le style d'une cellule de colonne , et sont répertoriés ici leur ordre de priorité, de le plus élevé au plus bas:

* DisplayMemberBinding 
* CellTemplate 
* CellTemplateSelector 

voir aussi un C# Disciples post à ce sujet.

+0

Merci, cela ressemble en effet au problème. J'ai déjà modifié mon code pour utiliser un contrôle DataGrid fourni avec SP1. Il peut être plus approprié dans ma situation de toute façon. Mais c'est définitivement la bonne solution. Merci beaucoup! – Razzie

0

Je pense que le problème est que la chaîne que vous passez à FindResource() ne correspond pas à la clé de la ressource que vous avez défini dans le XAML. Essayez plutôt de passer au "NumberInStock" et voyez si cela fonctionne.

+0

de Sharp! Malheureusement, c'était simplement une erreur de copier-coller-éditer-pour-question de mon côté.Il pointe vers la bonne clé dans mon code. De plus, FindResource (chaîne) lève une exception lorsque la clé n'est pas trouvée. Merci quand même! – Razzie

2

c'est la meilleure façon d'insérer une image

 GridViewColumn column = new GridViewColumn { Header = "IM" };    
     DataTemplate template = new DataTemplate(); 

     FrameworkElementFactory factory = new FrameworkElementFactory(typeof(Grid)); 
     template.VisualTree = factory; 
     FrameworkElementFactory imgFactory = new FrameworkElementFactory(typeof(Image)); 

     Binding newBinding = new Binding("IMG"); 
     imgFactory.SetBinding(Image.SourceProperty,newBinding); 
     imgFactory.SetValue(Image.WidthProperty,15.0); 
     imgFactory.SetValue(Image.HeightProperty, 15.0); 

     factory.AppendChild(imgFactory); 
     column.CellTemplate = template; 
     view.Columns.Add(column); 

     ListViewMain.View = view; 

+0

Quelques explications supplémentaires seraient utiles, mais cela m'a conduit à la bonne réponse (sur mon cas). En un mot: _Cela va générer le créateur de contenu pour une colonne, de sorte que chaque ligne de l'usine est appelée pour générer des contrôles définis sur l'usine._ merci .. +1 –

+0

Ce style a fonctionné pour moi. Remarque: ma liaison était à une propriété d'une propriété d'objet enfant, donc il ressemblait à ceci: 'Binding newBinding = new Binding (" ChildProp.SubProp "); newBinding.Converter = nouveau MyConverter(); ' –

Questions connexes