Je ne sais pas si c'est encore pertinent, mais j'ai trouvé un moyen de styliser les cellules individuelles avec un sélecteur de cellule. Il est un peu hacky parce que vous avez à grignoter autour avec le contenu du ContentPresenter pour obtenir le DataContext approprié pour la cellule (de sorte que vous pouvez lier à l'élément de cellule réelle dans le modèle cellulaire):
public class DataMatrixCellTemplateSelectorWrapper : DataTemplateSelector
{
private readonly DataTemplateSelector _ActualSelector;
private readonly string _ColumnName;
private Dictionary<string, object> _OriginalRow;
public DataMatrixCellTemplateSelectorWrapper(DataTemplateSelector actualSelector, string columnName)
{
_ActualSelector = actualSelector;
_ColumnName = columnName;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// The item is basically the Content of the ContentPresenter.
// In the DataMatrix binding case that is the dictionary containing the cell objects.
// In order to be able to select a template based on the actual cell object and also
// be able to bind to that object within the template we need to set the DataContext
// of the template to the actual cell object. However after the template is selected
// the ContentPresenter will set the DataContext of the template to the presenters
// content.
// So in order to achieve what we want, we remember the original DataContext and then
// change the ContentPresenter content to the actual cell object.
// Therefor we need to remember the orginal DataContext otherwise in subsequent calls
// we would get the first cell object.
// remember old data context
if (item is Dictionary<string, object>)
{
_OriginalRow = item as Dictionary<string, object>;
}
if (_OriginalRow == null)
return null;
// get the actual cell object
var obj = _OriginalRow[_ColumnName];
// select the template based on the cell object
var template = _ActualSelector.SelectTemplate(obj, container);
// find the presenter and change the content to the cell object so that it will become
// the data context of the template
var presenter = WpfUtils.GetFirstParentForChild<ContentPresenter>(container);
if (presenter != null)
{
presenter.Content = obj;
}
return template;
}
}
Note: I a changé le DataMatrix à partir de l'article CodeProject afin que les lignes soient des Dictionnaires (ColumnName -> Cell Object).
Je ne peux pas garantir que cette solution ne casse pas quelque chose ou ne se casse pas dans le futur.Sortie nette. Il repose sur le fait que ContentPresenter définit DataContext après avoir sélectionné le modèle dans son propre contenu. (Réflecteur aide beaucoup dans ces cas :))
Lors de la création des GridColumns, je fais quelque chose comme ça:
var column = new GridViewColumn
{
Header = col.Name,
HeaderTemplate = gridView.ColumnHeaderTemplate
};
if (listView.CellTemplateSelector != null)
{
column.CellTemplateSelector = new DataMatrixCellTemplateSelectorWrapper(listView.CellTemplateSelector, col.Name);
}
else
{
column.DisplayMemberBinding = new Binding(string.Format("[{0}]", col.Name));
}
gridView.Columns.Add(column);
Note: J'étendu ListView de sorte qu'il possède une propriété CellTemplateSelector vous pouvez lier à en XAML
@EDIT 15/03/2011: J'ai écrit un petit article qui a un petit projet de démonstration ci-joint: http://codesilence.wordpress.com/2011/03/15/listview-with-dynamic-columns/
C'est comme ça que je veux faire mais pas clair comment. Les Props attachés et les PDD sont toujours un mystère pour moi. Tout exemple serait apprécié. A eu un coup d'oeil à ceci (https://rachel53461.wordpress.com/2011/09/17/wpf-grids-rowcolumn-count-properties/). Est-ce ainsi? – VivekDev