Question

Je souhaite afficher des données dans une grille de données wpftoolkit contenant des données

.
public class Thing
{
    public string Foo { get; set; }
    public string Bar { get; set; }
    public List<Candidate> Candidates { get; set; }
}

public class Candidate
{

    public string Name { get; set; }
    public CandidateType CandidateType { get; set; }
}

public enum CandidateType
{
    Type1,
    Type2,
    Type42
}

où le nombre de candidats dans la liste des candidats est configurable à l'exécution.

La disposition de grille souhaitée ressemble à ceci

Foo | Bar | Candidat 1 | Candidat 2 | ... | Candidat N

Il semble donc que je ne puisse pas créer de DataTemplate pour les candidats dans xaml car l'expression de liaison va changer.

J'ajoute les colonnes nécessaires à l'événement AutoGeneratedColumns comme suit:

private void DataGrid_AutoGeneratedColumns(object sender, EventArgs e)
{
    ViewModel vm = DataContext as ViewModel;

    for (int i = 0; i < vm.LotsOfThings.First().Candidates.Count; i++)
    {
        string assName = Assembly.GetExecutingAssembly().GetName().Name;
        ParserContext ctx = new ParserContext();
        ctx.XamlTypeMapper = new XamlTypeMapper(new string[] { assName });
        ctx.XamlTypeMapper.AddMappingProcessingInstruction("src", "WpfToolkitDataGridTester", assName);
        ctx.XmlnsDictionary.Add("", "http://schemas.microsoft.com/winfx/2006/xaml/presentation");
        ctx.XmlnsDictionary.Add("x", "http://schemas.microsoft.com/winfx/2006/xaml");
        ctx.XmlnsDictionary.Add("src", "clr-namespace:WpfToolkitDataGridTester;assembly=" + assName);
        var template = XamlReader.Parse(@"<DataTemplate>
                                            <DataTemplate.Resources>
                                                <src:FooConverter x:Key='fooConverter' />
                                            </DataTemplate.Resources>
                                            <TextBlock  
                                                Foreground='{Binding Candidates[" + i + @"].CandidateType,Converter={StaticResource fooConverter}}'
                                                Text='{Binding Candidates[" + i + @"].Name}' />
                                        </DataTemplate>", ctx) as DataTemplate;
        dg.Columns.Add(new DataGridTemplateColumn
        {
            Header = "Candidate " + (i + 1),
            CellTemplate = template
        });
    }
}

Cependant, cela échoue avec l'exception suivante: La balise 'FooConverter' n'existe pas dans l'espace de noms XML 'espace de noms clr: WpfToolkitDataGridTester; assembly = WpfToolkitDataGridTester'. Ligne '3' Position '54'.

La modification de StaticResource en DynamicResource ne change rien.

Qu'est-ce qui me manque?

FWIW: un modèle de données codé en dur

<DataTemplate x:Key="candidateTemplate">
  <DataTemplate.Resources>
    <src:FooConverter x:Key="fooConverter" />
  </DataTemplate.Resources>
  <TextBlock 
    Foreground="{Binding Candidates[0].CandidateType,Converter={StaticResource fooConverter}}"
    Text="{Binding Candidates[0].Name}" />
</DataTemplate>

et la colonne de modèle définie comme telle

<wpftk:DataGridTemplateColumn CellTemplate="{StaticResource candidateTemplate}" />

'fonctionne' mais ne produit évidemment pas le résultat souhaité, car Candidates [0] est codé en dur.

Était-ce utile?

La solution

Pour une raison quelconque, cela fonctionne comme prévu si je fais comme ça ...

    string assName = Assembly.GetExecutingAssembly().GetName().Name;
    StringBuilder sb = new StringBuilder();
    sb.Append("<DataTemplate ");
    sb.Append("xmlns='http://schemas.microsoft.com/winfx/2006/xaml/presentation' ");
    sb.Append("xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml' ");
    sb.Append("xmlns:src='clr-namespace:WpfToolkitDataGridTester;assembly=" + assName + "' >");
    sb.Append("<DataTemplate.Resources>");
    sb.Append("<src:FooConverter x:Key='fooConverter' />");
    sb.Append("</DataTemplate.Resources>");
    sb.Append("<TextBlock ");
    sb.Append("Foreground='{Binding Candidates[" + i + "].CandidateType,Converter={StaticResource fooConverter}}' ");
    sb.Append("Text='{Binding Candidates[" + i + @"].Name}' />");
    sb.Append("</DataTemplate>");
    var template = (DataTemplate)XamlReader.Parse(sb.ToString());

Autres conseils

Lorsque les fichiers XAML sont compilés au format BAML, il fait référence à l'assembly , pas à la source en mémoire. Le BAML étant compilé dans le même assemblage, le type actuel n’est pas encore disponible.

J'ai constaté qu'une solution de contournement à court terme consiste à commenter temporairement le style, à construire le projet, puis à restaurer le style.

La solution la plus permanente consiste toutefois à déplacer le convertisseur vers un autre assemblage.

Est-ce utile de déclarer le FooConverter une fois à un niveau supérieur (peut-être en tant que ressource du DataGrid ) au lieu de chaque DataTemplate ?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top