2017-09-27 2 views
0

J'essaie d'obtenir une liaison de données sur un WPF ListView pour fonctionner correctement mais pour une raison quelconque, il utilisera toujours la valeur fournie par ToString indépendamment de ce que j'ai essayé.Liaison de données WPF vers ObservableCollection - ItemTemplate ne pas modifier la valeur affichée

Comme il est, j'ai quelque chose comme ce qui suit:

private Controllers.ListController controller; 
public ListTest() 
{ 
    // ... 
    listView.DataContext = controller; 
} 
private void Page_Loaded(object sender, RoutedEventArgs e) 
{ 
    var t = new Task(() => 
    { 
     // some work to obtain data using controller... 
     Dispatcher.Invoke(() => 
     { 
      listView.ItemsSource = controller.TestListSource; 
     }); 
    }); 

    t.Start(); 
} 

Cela lie avec succès le ListView aux données fournies par le contrôleur et la vue de la liste affichera chaque entrée à l'intérieur du IEnumerable<TestListEntry>. Le problème est, je ne peux pas sembler changer comment le ListView montre chaque rangée. TestListEntry est la suivante:

public class TestListEntry 
{ 
    public string GivenName 
    { 
     get; set; 
    } 

    public string FamilyName 
    { 
     get; set; 
    } 

    public string DisplayName 
    { 
     get 
     { 
      return $"{ FamilyName }, { GivenName }"; 
     } 
    } 
} 

J'ai essayé d'abord de mettre ListBox.ItemTemplate comme ceci:

<ListView Grid.Row="2" x:Name="listView"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding DisplayName}"/> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="test" /> 
     </GridView> 
    </ListView.View> 
</ListView> 

Toutefois, cela ne change rien. Ayant WPF débogage de liaison activée montre trop rien en ce qui concerne une erreur aussi, ne montre quelque chose qui semble hors de propos si

System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=HorizontalContentAlignment; DataItem=null; target element is 'ListViewItem' (Name=''); target property is 'HorizontalContentAlignment' (type 'HorizontalAlignment') 
System.Windows.Data Information: 10 : Cannot retrieve value using the binding and no valid fallback value exists; using default instead. BindingExpression:Path=VerticalContentAlignment; DataItem=null; target element is 'ListViewItem' (Name=''); target property is 'VerticalContentAlignment' (type 'VerticalAlignment') 

J'ai aussi essayé de définir une couleur de fond sur le TextBlock intérieur ItemTemplate et il n'a pas changé quoi que ce soit soit , donc je ne sais pas ce qui se passe là-bas. J'ai ensuite essayé de mettre DisplayNamePath et SelectedValuePath

<ListView ItemsSource="{Binding}" Grid.Row="2" x:Name="researcherListView" DisplayMemberPath="DisplayName" SelectedValuePath="DisplayName"> 

qui ne change rien non plus. Je sais que je pourrais changer ToString pour contourner ce problème, mais j'ai un sentiment que je suis juste manque quelque chose ...

+0

@ mm8 Oui, c'est le cas. Il est implémenté en tant que 'ObservableCollection ' bien que – Mythrillic

+0

J'ai testé votre code en utilisant 'ListBox.ItemTemplate' et cela fonctionne parfaitement. Avez-vous des styles implicites ou des templates pour 'ListBox',' TextBlock' ou 'TestListEntry'? (Cela expliquerait également les messages 'System.Windows.Data Information'.) Si ce n'est pas le cas, veuillez isoler le problème et publier un [Exemple minimal, complet et vérifiable] (https://stackoverflow.com/help/mcve) nous pouvons trouver le coupable. – haindl

+0

@haindl excuses, je mettais 'ListView.View' et j'ai oublié de l'inclure dans ma réponse. Ce qui peut être corrigé en définissant 'DisplayMemberBinding =" {Binding DisplayName} "' - pourquoi est-ce?Chaque colonne hérite-t-elle de sa liaison de 'GridViewColumn' de ListView.View's si vous l'avez définie? – Mythrillic

Répondre

1

Si vous utilisez un <GridView> dans le <ListView.View> vous devez dire <GridViewColumn> comment afficher son contenu TestListEntry dans les cellules générées. Si ce n'est pas le cas, alors .ToString() est le seul moyen possible car c'est la seule information que chaque objet a.
L'utilisation du <ListBox.ItemTemplate> n'est tout simplement pas suffisante car il ne sait rien sur les colonnes spécifiques.

Pour contrôler le contenu affiché, vous pouvez soit définir la liaison directement, comme vous l'avez mentionné dans votre commentaire:

<GridViewColumn Header="test" DisplayMemberBinding="{Binding Path=DisplayName}" /> 

Ou vous pouvez définir le <GridViewColumn.CellTemplate> en utilisant votre <DataTemplate>:

<GridViewColumn Header="test"> 
    <GridViewColumn.CellTemplate> 
     <DataTemplate> 
      <TextBlock Text="{Binding DisplayName}" /> 
     </DataTemplate> 
    </GridViewColumn.CellTemplate> 
</GridViewColumn> 

L'utilisation d'un <DataTemplate> serait sûrement la meilleure solution si vous voulez styler vos cellules un peu plus que simplement afficher le texte.