2017-10-17 2 views
2

Je suis tout à fait nouveau à WPF et je suis coincé avec la situation ci-dessous:Comment changer le datacontext pour DataGridComboBoxColumn en une classe spécifique?

class Person{ 
    string Name; 
    List<Address> ListAddresses; 
} 

J'ai un DataGrid avec ItemsSource comme ObservableCollection<Person>. Cette collection est dans la classe MainViewModel. Je veux créer un DataGridComboBoxColumn avec les adresses.

<DataGrid ItemsSource="{Binding Persons, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"> 
    <DataGrid.Columns> 
     <DataGridComboBoxColumn ItemsSource="{Binding Path=ListAddresses, RelativeSource={RelativeSource Mode=FindAncestor, 
     AncestorType={x:Type local:Person}}}"> 
     </DataGridComboBoxColumn>  
    </DataGrid.Columns> 
</DataGrid> 

Je reçois l'erreur suivante:

System.Windows.Data Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='PersonApp.UL.ViewModels.Person', AncestorLevel='1''. BindingExpression:Path=ListAddresses; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=11440639); target property is 'ItemsSource' (type 'IEnumerable')

+0

Vous mentionnez 'MainViewModel', vous utilisez donc la structure MVVM? –

+0

Oui. J'utilise MVVM. –

Répondre

0

DataGridComboBoxColumn va vous causer beaucoup de problèmes. Essayez ceci:

<DataGridTemplateColumn Header="Something" 
          SortMemberPath="[SelectedAddress].[property from Address class]"> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <ComboBox ItemsSource="{Binding ListAddresses}" 
          SelectedItem="{Binding SelectedAddress, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" 
          SelectedValuePath="[SelectedAddress].[property from Address class]" 
          DisplayMemberPath="[property from Address class (like Name)]" /> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 

Vous devez également inclure SelectedAddress propriété dans votre Person classe, pour stocker Address est sélectionné dans le ComboBox.

Reliure à la propriété qui se trouve dans votre champ ItemsSource (qui dans ce cas est ce que vous liez à DataGrid) ne nécessite pas RelativeSource liaison, c'est la raison pour laquelle vous obtenez une erreur. RelativeSource est nécessaire dans le cas où vous définissez votre DataGrid.ItemsSource à par exemple PeopleList et vous voulez lier votre (c'est dans ce DataGrid) ComboBox.ItemsSource à une propriété qui est dans votre ViewModel, mais PAS à l'intérieur de votre PeopleList.

Une autre chose pour la liaison à ComboBox est si vous liez ItemsSource à une collection d'objets autres que strings, vous devez définir DisplayMemberPath à une propriété dans votre objet, afin de faire afficher le contrôle de la bonne légende. Donc par exemple si vous liez l'objet Car et qu'il a une propriété de type string appelée Name, vous devez définir DisplayMemberPath à Name afin de rendre votre liste d'affichage de contrôle de Car.Names (en sélectionner une aura toujours comme résultat de sélectionner l'objet entier, pas seulement le Propriété Name).

+0

Vous avez sauvé ma journée! Merci beaucoup pour la réponse détaillée et rapide! –

+0

Je suis content que je puisse vous aider :) –

+0

Aussi, si vous avez besoin d'une liaison à l'ancêtre, vous devriez plutôt essayer de trouver un ancêtre par type de contrôle, pas par objet du type 'ViewModel'. Par exemple, si vous avez 'View' qui est un' UserControl' et qu'il contient un 'DataGrid', alors vous devriez rechercher l'ancêtre de type' {x: Type UserControl} '. Cela vous donnera le 'DataContext' de votre' UserControl', qui (si vous implémentez MVVM correctement) est votre 'ViewModel' lié à votre' UserControl'. –