简体   繁体   中英

How to Bind a One To Many Relation in C# MVVM

I have been developing Windows Forms applications and am new to using the MVVMLight Toolkit and WPF.

My model is the following:

Patient

Id, FirstName, LastName, etc...

TestResult

Id, Score, Date,
PatientId, etc...

Each Patient can have multiple TestResults. On the same view (named GTPView), I want to display a listbox of Patients, and a listbox of TestResults. When the user clicks on a Patient, all of that Patient's TestResults should appear in the TestResults listbox.

I know how to bind the SelectedItem of the Patients ListBox to a Patient property from my GTPViewModel, but how do I bind the TestResults ListBox to all TestResults of the currently selected Patient?

Should I have a UserControl View of the TestResults listbox, and a UserControl View of the Patients listbox, and then add both these UserControls to my GTPView? Or is it best to just do it all on one view?

Thanks in advance. Let me know if you need more information. Here's the XAML for my GTPView:

<Window x:Class="ApuntaNotas.Views.GTPView"            
        Title="GTP"            
        DataContext="{Binding GTP, Source={StaticResource Locator}}"
        d:DataContext="{d:DesignData /SampleData/PatientsViewModelSampleData.xaml}">
    <Window.Resources>
        <CollectionViewSource Source="{Binding Patients}" x:Key="PatientsVS">
            <CollectionViewSource.SortDescriptions>
                <ComponentModel:SortDescription PropertyName="Name" />
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
    </Window.Resources>
    <DockPanel>
        <ListBox DockPanel.Dock="Left" ItemsSource="{Binding Source={StaticResource PatientsVS}}"
                 x:Name="listBoxPatients" SelectedItem="{Binding SelectedPatient}" DataContext="{Binding}"
                 DisplayMemberPath="">
        </ListBox>
        <ListBox DockPanel.Dock="Right" ItemsSource="{Binding Source={StaticResource PatientsVS}}"
                 x:Name="listBoxTestResults"  DataContext="{Binding}"
                 DisplayMemberPath="">
        </ListBox>

    </DockPanel>
</Window>

Your PatientViewModel should be like this

public class PatientViewModel: INotifyPropertyChanged
    {
       public int ID {get; set;}
       public string FirstName {get; set;}
       public string LastName {get; set;}
       //Each patient has a set of test results, so we create a list.
       public  List<TestResult> PatientTestResults {get; set;}
    }

You should have one more class which holds collection of PatientViewModel .

    public class AllPatients
    {
        public ObservableCollection<PatientViewModel> AllPatients{get; set;}
        public PatientViewModel SelectedPatient {get; set;}
    }

Your Window class should now look like this

  <ListBox x:Name="listBoxPatients" 
           ItemsSource="{Binding  AllPatients}"
           SelectedItem="{Binding SelectedPatient}"
           IsSynchronizedWithCurrentItem="True"/>

  <ListBox x:Name="listBoxTestResults"
           ItemsSource="{Binding SelectedPatient.TestResults}"
           IsSynchronizedWithCurrentItem="True"/>                 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM