2010-06-15 3 views
3

Ok le titre peut être un peu déroutant. J'ai une base de données avec la table Companies qui a une relotion one-to-many avec une autre table Divisions (de sorte que chaque entreprise peut avoir plusieurs divisions) et la division aura beaucoup d'employés.Liste des éléments d'un objet sélectionné dans une autre vue de liste

J'ai un ListView des compagnies. Ce que je ne veux pas, c'est que lorsque je choisis une entreprise de ListView, une autre ListView des divisions de cette société apparaît en dessous. Ensuite, je choisis une division et une autre liste des employés au sein de cette division appaers ci-dessous. Vous obtenez l'image.

Y at-il de toute façon à faire cela principalement dans le code XAML de façon déclarative (sp?). J'utilise linq pour que les objets d'entité Company aient une propriété nommée Division qui, si je comprends bien, linq devrait inclure les objets Division des divisions connectées à la société. Donc, après avoir obtenu toutes les entreprises et les mettre comme une source d'articles à CompanyListView c'est où je suis actuellement.

<ListView x:Name="CompanyListView" 
       DisplayMemberPath="CompanyName" 
       Grid.Row="0" Grid.Column="0" /> 

    <ListView DataContext="{Binding ElementName=CompanyListView, Path=SelectedItem}" 
       DisplayMemberPath="Division.DivisionName" 
       Grid.Row="1" Grid.Column="0" /> 

Je sais que je suis loin mais j'espérais en mettant quelque chose de spécifique dans le DataContext et DisplayMemberPath je pouvais obtenir ce travail. Si ce n'est pas le cas, je dois capturer l'identifiant de l'entreprise et capturer un événement sélectionné ou quelque chose.

Un autre problème mais lié est la dans la deuxième colonne à côté de la lisview je ne voulais pas avoir une vue de détails/modifier pour l'élément sélectionné. Donc, quand seulement une entreprise est sélectionnée, des détails à ce sujet apparaîtront alors quand une division dans l'entreprise est choisie.

Répondre

2

Vous pouvez utiliser le modèle MVVM pour lier votre code XAML à une classe qui contient des informations pour vos ListViews et réinitialiser le contenu de la collection Division en fonction de l'élément Comany sélectionné.

Voici un exemple de base pour vous aider à démarrer.

Voici deux contrôles ListView dans XAML:

<Window x:Class="MultiListView.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Main Window" Height="400" Width="800"> 
    <DockPanel> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 
     <ListView Grid.Row="0" 
        ItemsSource="{Binding Companies}" 
        SelectedItem="{Binding Company, Mode=TwoWay}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Name" 
            DisplayMemberBinding="{Binding CompanyName}" /> 
        <GridViewColumn Header="Description" 
            DisplayMemberBinding="{Binding Description}" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 
     <ListView Grid.Row="1" 
        ItemsSource="{Binding Divisions}" 
        SelectedItem="{Binding Division, Mode=TwoWay}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Name" 
            DisplayMemberBinding="{Binding DivisionName}" /> 
        <GridViewColumn Header="Description" 
            DisplayMemberBinding="{Binding Description}" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 
    </Grid> 
    </DockPanel> 
</Window> 

Dans le code-behind définir le DataContext pour la fenêtre à une classe de gestion contient les références de liaison utilisés dans le XAML.

public partial class MainView : Window 
{ 
    MainViewModel _mvm = new MainViewModel(); 

    public MainView() 
    { 
     InitializeComponent(); 
     DataContext = _mvm; 
    } 
} 

La classe suivante utilise le modèle MVVM, que vous pouvez trouver beaucoup d'informations dans Stackoverflow. Cette classe contient les données avec lesquelles le XAML se lie. Ici, est l'endroit où vous pouvez utiliser LINQ pour charger/recharger les collections.

using System.Collections.ObjectModel; 
using MultiListView.Models; 

namespace MultiListView.ViewModels 
{ 
public class MainViewModel : ViewModelBase 
{ 
    public MainViewModel() 
    { 
    _companies = new ObservableCollection<Company>(); 
    _companies.Add(new Company("Stackoverflow", "QA web site")); 
    _companies.Add(new Company("Fog Creek", "Agile Bug Tracking")); 
    _companies.Add(new Company("Second Beach", "Not sure yet")); 

    _divisions = new ObservableCollection<Division>(); 
    } 

    private ObservableCollection<Company> _companies; 
    public ObservableCollection<Company> Companies 
    { 
    get { return _companies; } 
    set 
    { 
     _companies = value; 
     OnPropertyChanged("Companies"); 
    } 
    } 

    private Company _company; 
    public Company Company 
    { 
    get { return _company; } 
    set 
    { 
     _company = value; 

     // load/reload divisions for the selected company here 
     LoadDivisions(); 

     OnPropertyChanged("Company"); 
    } 
    } 

    // hack to keep the example simpe... 
    private void LoadDivisions() 
    { 
    _divisions.Clear(); 

    // use db or linq here to filiter property 
    if (_company != null) 
    { 
     if (_company.CompanyName.Equals("Stackoverflow")) 
     { 
      _divisions.Add(new Division("QA", "Test all day")); 
      _divisions.Add(new Division("Write", "Doc all day")); 
      _divisions.Add(new Division("Code", "Code all day")); 
     } 
     else if (_company.CompanyName.Equals("Fog Creek")) 
     { 
      _divisions.Add(new Division("Test", "Test all day")); 
      _divisions.Add(new Division("Doc", "Doc all day")); 
      _divisions.Add(new Division("Develop", "Code all day")); 
     } 
     else if (_company.CompanyName.Equals("Second Beach")) 
     { 
      _divisions.Add(new Division("Engineering", "Code all day")); 
     } 
    } 
    } 

    private ObservableCollection<Division> _divisions; 
    public ObservableCollection<Division> Divisions 
    { 
    get { return _divisions; } 
    set 
    { 
     _divisions = value; 
     OnPropertyChanged("Divisions"); 
    } 
    } 

    private Division _division; 
    public Division Division 
    { 
    get { return _division; } 
    set 
    { 
     _division = value; 
     OnPropertyChanged("Division"); 
    } 
    } 
} 
} 

OnPropertyChanged implémente INotifyPropertyChanged.
Lorsque les propriétés d'un ViewModel sont modifiées, les vues liées au ViewModel reçoivent une notification lorsque ViewModel déclenche son événement PropertyChanged.

Vous trouverez des exemples dans la plupart des bibliothèques MVVM ou un exemple dans MSDN.

+0

Où cette méthode OnPropertyChanged viennent et que fait-il? –

+0

J'ai ajouté plus de détails sur OnPropertyChanged à la fin de ma réponse. – Zamboni

+0

Ok, qu'en est-il de la boîte de détails dynamique qui montre les détails sur la société/Dicision/employé en fonction de qui est sélectionné. TreeView est quelque chose que je devrais regarder? –

3

Si divisions est une propriété de la société, vous pourriez probablement faire quelque chose comme ceci:

<Window x:Class="MultiListView.Views.MainView" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="Main Window" Height="400" Width="800"> 
    <DockPanel> 
    <Grid> 
     <Grid.RowDefinitions> 
      <RowDefinition/> 
      <RowDefinition/> 
     </Grid.RowDefinitions> 
     <ListView Grid.Row="0" 
        x:Name="lvCompanies" 
        ItemsSource="{Binding Companies}" 
        SelectedItem="{Binding Company, Mode=TwoWay}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Name" 
            DisplayMemberBinding="{Binding CompanyName}" /> 
        <GridViewColumn Header="Description" 
            DisplayMemberBinding="{Binding Description}" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 
     <ListView Grid.Row="1" 
        ItemsSource="{Binding ElementName='lvCompanies', Path=SelectedItem.Divisions}" 
        SelectedItem="{Binding Division, Mode=TwoWay}"> 
      <ListView.View> 
       <GridView> 
        <GridViewColumn Header="Name" 
            DisplayMemberBinding="{Binding DivisionName}" /> 
        <GridViewColumn Header="Description" 
            DisplayMemberBinding="{Binding Description}" /> 
       </GridView> 
      </ListView.View> 
     </ListView> 
    </Grid> 
    </DockPanel> 
</Window> 
Questions connexes