Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
first of all please do not confuse with my question title. It is a single seleteditem on Multiple datagrid ( not multipleselecteditems on a single datagrid).
 
I have multiple datagrids ( say three ), each datagrid from the lowest depends for its data from the selecteditem from the above datagrid. I have asked questions on selecteditem on datagrid by populating the data from a sqlserver few weeks ago, and i managed to solve this issue with some answers.
 
WPF SelectedItem binding between two datagrids[^]
 
is it possible to use the same selecteditem of a datagrid on multiple datagrid's ? for example,in the previous problem it was only 1:1 datagrid, will it be possible to implement the same concept like there are three datagrids,
 
one - Person
 
two- PersonDetails
 
Three- PersonStatus
 
1. first the Person datagrid loads by default (from the database)
 
2. Persondetails table data is displayed when a selecteditem is clicked on the Person datagrid(achieved this already)
 
3. PersonStatus table data should be displayed when the selecteditem is clicked on Persondetails( is this possible, it is like a tree one after the other)
 
This is how it will look like, I have achieved the selecteditem between the first two datagrid's
 
http://postimage.org/image/4cpoi2e07/[^]
 
My MainViewModel.cs
 
//Datacontext
        public MainViewModel()
        {
            this.Persons = Person.GetPersons();
        }
     
        // for Person Datagrid
        private ObservableCollection<Person> personValues;
        public ObservableCollection<Person> Persons
        {
            get { return personValues; }
            set { this.SetProperty<ObservableCollection<Person>>(ref this.personValues, value); }
        }
 
       //for the PersonDetails datagrid
        public ObservableCollection<PersonDetails> Details
        {
            get
            {
                if (this.Selectedperson == null)
                {
                    return null;
                }
                return this.LoadDetails(this.Selectedperson.PersonID);
            }
 
        }
        // method to load the persondetails data
        private ObservableCollection<PersonDetails> LoadDetails(int personID)
        {
            ObservableCollection<PersonDetails> details = new ObservableCollection<PersonDetails>();
            foreach (PersonDetails detail in PersonDetails.GetDetails().Where(item => item.PersonID == personID))
            {
                details.Add(detail);
            }
            return details;
        }
 
        // SelectedPerson Property
        private Person selectedPersonValue;
        public Person Selectedperson
        {
            get { return selectedPersonValue; }
            set
            {
                this.SetProperty<Person>(ref this.selectedPersonValue, value);
                this.RaiseNotification("Details");
            }
        }
 
        //for the PersonStatus datagrid
        public ObservableCollection<PersonStatus> Statuses
        {
            get 
            {
                if (this.SelectedDetail == null)
                {
                    return null;
                }
                return this.LoadStatus(this.SelectedDetail.DetailID);
            }
        }
 
        // method for loading the Status details
        private ObservableCollection<PersonStatus> LoadStatus(int detailID)
        {
            ObservableCollection<PersonStatus> statuss = new ObservableCollection<PersonStatus>();
            foreach (PersonStatus status in PersonStatus.GetStatus().Where(item => item.DetailID == detailID))
            {
                statuss.Add(status);
            }
            return statuss;
        }
 
        // SelectedDetail Property
        private PersonStatus selectedDetail;
        public PersonStatus SelectedDetail
        {
            get { return selectedDetail; }
            set
            {
                this.SetProperty<PersonStatus>(ref this.selectedDetail, value);
                this.RaiseNotification("Statuses");
            }
        }
 
XAML
 
 <Grid>
        <DataGrid Margin="100,12,116,219" ItemsSource="{Binding Persons}" SelectedItem="{Binding Selectedperson, Mode=TwoWay}"  />
        <DataGrid Margin="100,110,116,121" ItemsSource="{Binding Details}" SelectedItem="{Binding SelectedDetail,Mode=TwoWay}" />
        <DataGrid ItemsSource="{Binding Statuses}" Margin="100,210,116,21" />
    </Grid>
 

when I try this code i get this following error :
http://s10.postimage.org/bxk7etjjd/SOerror.png[^]
 
kindly help to proceed further. Thanks
Posted 26-Feb-13 4:27am
Comments
Jason Gleim at 26-Feb-13 9:55am
   
Set a breakpoint at the top of that method and step through it using F11. Make sure that it isn't being called a bunch of times. It could be that when you populate the first grid, SelectedItem is being set to each row as it is being inserted into the grid. (You could test this by putting a breakpoint in the SelectedItem property setter and running the app. If it breaks there when the first grid is being filled in, then that is the problem.) This could be causing GetDetails to be called for every row in the top grid (recursively too I believe). That would definitely cause a stack overflow.
 
If this is the case, you may need to add some logic to inhibit getting the details while a grid is being updated. Since you have methods to get the data for a grid, set a flag at the beginning and use that in the lower grid GetDetails methods to skip over getting the details if the flag is set. Really, you don't want to get the details until a user selects a row anyway so it won't hurt doing this.
BuBa1947 at 26-Feb-13 10:37am
   
I have already tried using breakpoint at top of the method. everything works fine until I select the item in the second datagrid, there it takes a pause for 3-4 secs and an exception occurs at da.Fill(row) :(
 
http://s23.postimage.org/shhz62bjf/Soerror2.png
 
I suspect here,
 
do I have to create a separate property again for <PersonDetails> as
 
private ObservableCollection<PersonDetails> personDetails;
public ObservableCollection<PersonDetails> Details
{
get { return personDetails; }
set { this.SetProperty>(ref this.personDetails, value); }
}
 
but this creates duplicate for Details.
 
did u have a look at my MainViewModel. is everything ok there Mr.Jason. what do u think?
Jason Gleim at 26-Feb-13 14:18pm
   
I'm curious why you would get a stack overflow filling the data adapter. Do you have a huge number of rows in the database? Are you sure da.Fill isn't being called recursively?
 
You might try using a SqlDataReader rather than the SqlDataAdapter since it looks like you are only reading the data from the DB and not updating anything. The DataReader is more efficient in these situations. Although I don't know if that will fix it or not. I'm not a data guy so that is a bit out of my expertise.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 381
1 Sergey Alexandrovich Kryukov 245
2 Marcin Kozub 225
3 Praneet Nadkar 217
4 /\jmot 189
0 OriginalGriff 8,284
1 Sergey Alexandrovich Kryukov 7,407
2 DamithSL 5,614
3 Maciej Los 4,989
4 Manas Bhardwaj 4,986


Advertise | Privacy | Mobile
Web03 | 2.8.1411023.1 | Last Updated 26 Feb 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100