2009-02-24 11 views
5

No se pudo encontrar una respuesta a esta.WPF - Establecer DataTemplate para GridViewColumns agregadas mediante programación

Tengo un control WPF ListView que puede contener un número variable de columnas. Por ejemplo, puede mostrar datos de clientes, mostrar columnas Id, Nombre, Correo electrónico, etc., o puede contener productos, mostrando ID, Nombre, Precio, NumberInStock, Fabricante, bueno, se entiende la idea: varía el número de columnas, los nombres varían.

Lo que quiero hacer es que ciertas columnas muestren los datos de forma diferente. Por ejemplo, en lugar de imprimir 'Sí' o 'No' como el valor de la columna NumberInStock, quiero mostrar una imagen nítida.

Si tuviera una cantidad fija de columnas, con nombres fijos para vincular, veo cómo es fácil. Simplemente defina un DataTemplate para esa columna en particular y lo usaría para definir la vista de mi columna. Sin embargo, no puedo ver cómo hacerlo en mi situación.

Soy muy nuevo en WPF, así que disculpe si mi enfoque es malo :-) En mi XAML, he definido un control ListView, que está prácticamente vacío. En mi código detrás, yo uso:

// 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); 
     } 

bien, estoy seguro de que esto se podría hacer un poco más bonito (si tiene algún consejo, por favor!) Pero el mayor problema es que no puedo ver ninguna diferencia en la columna. Simplemente muestra el valor de texto de la columna 'NumberInStock'. Mi DataTemplate se define en el 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> 

Por supuesto, todavía tendría que añadir la funcionalidad que sería mostrar un 'sí' o 'no' de imagen en función del valor de NumberInStock, pero eso es un paso 2 realmente ¡Me encantaría ver una imagen y un borde rojo en mi ListView!

Gracias de antemano, Razzie

Respuesta

7

Esto me hizo perder un tiempo.

DisplayMemberBinding y CellTemplate son mutuamente excluyentes. Si se especifica DisplayMemberBinding, se ignorará el CellTemplate.

De MSDN:

Las siguientes propiedades son utilizados para definir el contenido y el estilo de una célula columna, y se enumeran aquí en su orden de precedencia, desde mayor a menor:

* DisplayMemberBinding 
* CellTemplate 
* CellTemplateSelector 

ver también un C# Disciples post sobre esto.

+0

Gracias, eso se ve realmente como el problema. Ya edité mi código para usar un control DataGrid que viene con SP1. Puede ser más adecuado en mi situación de todos modos. Pero esta es definitivamente la solución correcta. ¡Muchas gracias! – Razzie

0

Creo que el problema es que la cadena que estás pasando a FindResource() no coincide con la clave del recurso que ha definido en el XAML. Intenta pasar "NumberInStock" en su lugar y mira si eso funciona.

+0

agudo! Desafortunadamente, fue solo un error de copiar y pegar-corregir-por-pregunta de mi lado.Apunta a la clave correcta en mi código. Además, FindResource (cadena) arroja una excepción cuando no se encuentra la clave. ¡Gracias de cualquier manera! – Razzie

2

Ésta es la manera más fácil de insertar una imagen

 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

Algunas explicaciones más serían útiles, pero esto me llevó a la respuesta correcta (en mi caso). En pocas palabras: _Esto generará el creador de contenido para una columna, por lo que cada fila de la fábrica está llamada a generar controles definidos en la fábrica._ gracias .. +1 –

+0

Este estilo funcionó para mí. NOTA: Mi enlace era una propiedad de un objeto secundario, por lo que se veía así: 'Enlace newBinding = new Binding (" ChildProp.SubProp "); newBinding.Converter = new MyConverter(); ' –

Cuestiones relacionadas