title: XAML Binding to Sql Server
body: <p>I have a SQL Server DB with the following tables and relationships:</p>
  
  <p>Jobs which contains many sessions.
  Sessions which contains many breaks.</p>
  
  <p>First of all, dont be frightened by the large amount of code posted here. The relevant parts are the highlighted parts dealing with the list, the rest is just for comparison to see where I am going wrong.</p>
  
  <p>In XAML I am trying and succeeding when binding jobs. I get it to filter out the correct sessions. No problem there.</p>
  
  <p>My problem is that when I try to get it to filter the breaks that belong to each session it wont work but I am using all the same principles.</p>
  
  <p>I am not using (nor interested in using) Linq2Sql as it creates too many additional classes that bloat my code. I am just using direct databinding.</p>
  
  <p>I have asked this question before and posted code, but I never got any reply because the code was simply too long to read in a reasonable timeframe.</p>
  
  <p>My question here is, what am I doing wrong. I was with the impression that since I can successfully bind and filter sessions, then I should be able to do likewise with sessions and filter breaks. But it doesnt work.</p>
  
  <p>I am getting somewhat desparate for help and appreicate any answers.</p>
  
  <p>EDIT: Once again I have included code samples. I am not trying to hide the code for secrecy and copyright. It is just an exercise I am doing to learn so I wouldnt mind posting the full code. But it is very long. So I will just post the parts I think are relevant. If you want more just ask.</p>
  
  <p>For those of you interested in skipping to the good part where the problems are, look under the part of the Breaks list box. The rest is just there for comparison to help you debug. There is also C# code below to help further. Again, look at the list part the rest is just for debugging.</p>
  
  <p>Below is the relevant XAML</p>
  
  <pre><code>&lt;!--Jobs List box - Works fine--&gt;
  &lt;ListBox Name="lstJobs"  DockPanel.Dock="Top"
          MinWidth="150" MinHeight="200" MaxHeight="250"
          ScrollViewer.VerticalScrollBarVisibility="Visible"
          SelectionChanged="lstJobs_SelectionChanged"
  
          IsSynchronizedWithCurrentItem="True"
          DataContext="{Binding Tables[JobDetails]}"
          ItemsSource="{Binding}"
          &gt;
      &lt;ListBox.ItemTemplate&gt;
          &lt;DataTemplate&gt;
              &lt;Grid&gt;
                  &lt;StackPanel Orientation="Horizontal" Margin="3,0,3,0"&gt;
                      &lt;TextBlock Text="{Binding Path=Title}"/&gt;
                      &lt;TextBlock Text=" "/&gt;
                      &lt;TextBlock Text="{Binding Path=ID}"/&gt;
                  &lt;/StackPanel&gt;
              &lt;/Grid&gt;
          &lt;/DataTemplate&gt;
      &lt;/ListBox.ItemTemplate&gt;
  &lt;/ListBox&gt;
  
  &lt;!--How Jobs listbox is bound to relevant fields in jobs table. This works fine--&gt;
  &lt;TextBox    Text="{Binding        ElementName=lstJobs, Path=SelectedItem.ID,            UpdateSourceTrigger=PropertyChanged}" Name="txtJobNo"          Grid.Row="1"                 IsEnabled="False"/&gt;
  &lt;TextBox    Text="{Binding        ElementName=lstJobs, Path=SelectedItem.Title,         UpdateSourceTrigger=PropertyChanged}" Name="txtJobTitle"       Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/&gt;
  &lt;TextBox    Text="{Binding        ElementName=lstJobs, Path=SelectedItem.Description,   UpdateSourceTrigger=PropertyChanged}" Name="txtJobDesc"        Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Grid.RowSpan="2"/&gt;
  
  
  &lt;!--Sessions List box, Automatically filtered based on relationship (see last binding line). This works fine too--&gt;
  &lt;ListBox Name="lstSessions" DockPanel.Dock="Top" MinWidth="150"
          MinHeight="200" MaxHeight="220"
          ScrollViewer.VerticalScrollBarVisibility="Visible"
          SelectionChanged="lstSessions_SelectionChanged"
  
          IsSynchronizedWithCurrentItem="True"
          DataContext="{Binding Path=Tables[JobDetails]}"
          ItemsSource="{Binding Path=relJobDetailsSessionDetails}"
          &gt;
      &lt;ListBox.ItemTemplate&gt;
          &lt;DataTemplate&gt;
              &lt;Grid&gt;
                  &lt;StackPanel Orientation="Horizontal" Margin="3,0,3,0"&gt;
                      &lt;TextBlock Text="{Binding Path=Title}" /&gt;
                      &lt;TextBlock Text="{Binding Path=ID}" /&gt;
                  &lt;/StackPanel&gt;
              &lt;/Grid&gt;
          &lt;/DataTemplate&gt;
      &lt;/ListBox.ItemTemplate&gt;
  &lt;/ListBox&gt;
  
  &lt;!--How Sessions listbox is bound to relevant fields in Sessions table. This works fine--&gt;
  &lt;TextBox Name="txtSessionNo"          Text="{Binding ElementName=lstSessions, Path=SelectedItem.ID,            UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="0"/&gt;
  &lt;TextBox Name="txtSessionTitle"       Text="{Binding ElementName=lstSessions, Path=SelectedItem.Title,         UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="3"/&gt;
  &lt;TextBox Name="txtSessionDesc"        Text="{Binding ElementName=lstSessions, Path=SelectedItem.Description,   UpdateSourceTrigger=PropertyChanged}" Grid.Row="2" Grid.Column="1" Grid.ColumnSpan="3" Grid.RowSpan="2"/&gt;
  
  
  &lt;!--Breaks List box, Should be automatically filtered (it is), but it does not change when a job or session is selected. Why?? --&gt;
  &lt;ListBox Name="lstBreaks" MinWidth="150" MinHeight="140" MaxHeight="140"
          ScrollViewer.VerticalScrollBarVisibility="Visible"
          SelectionChanged="lstBreaks_SelectionChanged"
  
          IsSynchronizedWithCurrentItem="True"
          DataContext="{Binding Path=Tables[SessionDetails]}"
          ItemsSource="{Binding Path=relSessionDetailsBreakDetails}"
          &gt;
      &lt;ListBox.ItemTemplate&gt;
          &lt;DataTemplate&gt;
              &lt;Grid&gt;
                  &lt;StackPanel Orientation="Horizontal" Margin="3,0,3,0"&gt;
                      &lt;TextBlock Text="{Binding Path=Title}" /&gt;
                      &lt;TextBlock Text="{Binding Path=ID}" /&gt;
                  &lt;/StackPanel&gt;
              &lt;/Grid&gt;
          &lt;/DataTemplate&gt;
      &lt;/ListBox.ItemTemplate&gt;
  &lt;/ListBox&gt;
  
  &lt;!--How Breaks listbox is bound to relevant fields in Breaks table. This works fine as before--&gt;
  &lt;TextBox Name="txtBreakNo"          Text="{Binding ElementName=lstBreaks, Path=SelectedItem.ID,            UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="0"/&gt;
  &lt;TextBox Name="txtBreakTitle"       Text="{Binding ElementName=lstBreaks, Path=SelectedItem.Title,         UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="2"/&gt;
  &lt;ComboBox Name="cbxBreakType"       Text="{Binding ElementName=lstBreaks, Path=SelectedItem.Description,     UpdateSourceTrigger=PropertyChanged}" Grid.Row="1" Grid.Column="3"/&gt;
  </code></pre>
  
  <p>Following is the C# Code behind (Once again, the highlighted part is the breaks and the rest is just for comparison, so you can skip directly to that if you like):</p>
  
  <pre><code>//Connection String
  string conString = "XYZ Works ok, no prob here";
  
  //Data Adaptors for various tables
  SqlDataAdapter daJobDetails = new SqlDataAdapter();
  SqlDataAdapter daSessionDetails = new SqlDataAdapter();
  SqlDataAdapter daBreakDetails = new SqlDataAdapter();
  
  //The dataset to hold all of the data
  DataSet dsDataSet = new DataSet();
  
  //Step 1: Create Connection
  SqlConnection conn = new SqlConnection(conString);
  
  //Open Connection
  conn.Open();
  
  
  //Load Job Details Table - works fine.
  daJobDetails.SelectCommand = new SqlCommand("Select * From JobDetails", conn);
  daJobDetails.Fill(dsDataSet, "JobDetails");
  
  //Load Session Details table - works fine.
  daSessionDetails.SelectCommand = new SqlCommand("SELECT * FROM SessionDetails", conn);
  daSessionDetails.Fill(dsDataSet, "SessionDetails");
  
  //Relation: JobDetails.ID = SessionDetails.JobID. - Works fine
  dsDataSet.Relations.Add("relJobDetailsSessionDetails",
      dsDataSet.Tables["JobDetails"].Columns["ID"],
      dsDataSet.Tables["SessionDetails"].Columns["JobID"]);
  
  
  //**** Possible problem code *****
  //Load Break Details table - could there be something wrong here.
  daBreakDetails.SelectCommand = new SqlCommand("SELECT * FROM BreakDetails", conn);
  daBreakDetails.Fill(dsDataSet, "BreakDetails");
  
  //**** Possible problem code *****
  //Relation: SessionDetails.ID = BreakDetails.SessionID - Could there be something wrong here
  dsDataSet.Relations.Add("relSessionDetailsBreakDetails",
      dsDataSet.Tables["SessionDetails"].Columns["ID"],
      dsDataSet.Tables["BreakDetails"].Columns["SessionID"]);
  
  
  
  //Set the DataContext to the DataSet
  expJobs.DataContext = dsDataSet;
  
  
  //Close connection
  conn.Close();
  </code></pre>