locked
WPF Data Binding with EF RRS feed

  • Question

  • Hi,

    i already read some answers that are close to my question, but I don`t know how to use it in my case.

    I tave 5 Tables, Table1 associated to Table2 (One to Many), Table2 associated to Table3, Table4, Table5 (each One to Many)

    Now I want to create a App in which I can select the data of Table1, grouped by values,in a ComboBox so that i only see the entries of Table1 in a ListView.

    Depending on my selection in the ListView, i see all associated entries of tabel2 in another ListView. Again, depending on the selection of Table2 i see the associated Values of Table3,4,5 inLIstViews.

    PseudoCode:

     <StackPanel>
          <ComboBox Name="cmbBoxTable1" ItemsSource="{Binding}"/>
          <ListView Name="lstViewTable1" DataContext="{Binding ElementName=cmbBoxTable1,Path=SelectedItem}"/>
          <ListView Name="lstViewTable2" DataContext="{Binding ElementName=lstViewTable1,Path=SelectedItem}"/>
          <ListView Name="lstViewTable3" DataContext="{Binding ElementName=lstViewTable2,Path=SelectedItem}"/>
          <ListView Name="lstViewTable4" DataContext="{Binding ElementName=lstViewTable2,Path=SelectedItem}"/>
          <ListView Name="lstViewTable5" DataContext="{Binding ElementName=lstViewTable2,Path=SelectedItem}"/>
        </StackPanel>
    


    I tried to fill the ComboBox with Linq: var item = from i in ModelContext.Table1 group i by i.id into g;

    But I can´t bind the ListView to the ComboBoxItems because in a grouping type...

    Hope you can help me !Happy for all Links and Hints !

    best regards

    • Moved by Larcolais Gong Friday, July 22, 2011 6:59 AM (From:ADO.NET Entity Framework and LINQ to Entities)
    Tuesday, July 19, 2011 8:44 PM

Answers

  • I "solved" it this way...

     

    private void tABLE1ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    		{
    			WpfApplication1.MyModelContainer myModelContainer = new WpfApplication1.MyModelContainer();
    			System.Windows.Data.CollectionViewSource tABLE1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("tABLE1ViewSource")));
    			System.Data.Objects.ObjectQuery<WpfApplication1.TABLE1> tABLE1Query = this.updateTABLE1Query(myModelContainer);
    			tABLE1ViewSource.Source = tABLE1Query.Execute(System.Data.Objects.MergeOption.AppendOnly);
    		}
    		private System.Data.Objects.ObjectQuery<TABLE1> updateTABLE1Query(MyModelContainer myModelContainer)
    		{
    			var queryCmb = gRID_IDComboBox.SelectedValue;
    
    			System.Data.Objects.ObjectQuery<WpfApplication1.TABLE1> tABLE1Query = myModelContainer.TABLE1.Where("it.GRID_ID = "+queryCmb);
    			// Aktualisiert die Abfrage so, dass sie TABLE2-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_1-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_1");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_2-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_2");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_3-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_3");
    			// Gibt eine ObjectQuery zurück.
    			return tABLE1Query;
    		}
    


    This works, and that is all I need ;-)

    thanks and best regards

    • Marked as answer by Dru_MS Monday, July 25, 2011 8:28 AM
    Monday, July 25, 2011 8:28 AM

All replies

  • I moved your post into WPF forum for further support.

    Thanks,


    Larcolais Gong[MSFT]
    MSDN Community Support | Feedback to us
    Get or Request Code Sample from Microsoft
    Please remember to mark the replies as answers if they help and unmark them if they provide no help.

    Friday, July 22, 2011 6:59 AM
  • Have you miss select clause in your LINQ? Post full code how you bind your ComboBox please (cmbBoxTable1.ItemsSource = ). This helps to reproduce your problem.
    Friday, July 22, 2011 7:44 AM
  • WIth the approach you're taking there, you would have to have all the data you're using in what you bind your combo to.

    But you haven't got all that data because you used linq to group by and you therefore only have one record per id.

     

    The simplest approach would be to have your combo data in one collection, grouped, containing a collection per record for your various tables.

    Or

    You could have one collection like you have now without all the listview's data.

    Bind your intemssource on the combo to your linq.

    Set the itemssource of your listviews in code rather than xaml.

    That would require the least knowledge of EF and Linq so might be the least risk.

    Then you can think about whether you want to learn more about them later once your deadline is hit.

     

    Friday, July 22, 2011 9:06 AM
  • Hi,

    this is my approach.

    private void Window_Loaded(object sender, RoutedEventArgs e)
    		{
    			
    			WpfApplication1.MyModelContainer myModelContainer = new WpfApplication1.MyModelContainer();
    			
    			//Loads the data
    			System.Windows.Data.CollectionViewSource tABLE1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("tABLE1ViewSource")));
    			System.Data.Objects.ObjectQuery<WpfApplication1.TABLE1> tABLE1Query = this.GetTABLE1Query(myModelContainer);
    			tABLE1ViewSource.Source = tABLE1Query.Execute(System.Data.Objects.MergeOption.AppendOnly);
    			gRID_IDComboBox.ItemsSource = myModelContainer.TABLE1.Select(g => g.GRID_ID).Distinct();
    			gRID_IDComboBox.SelectedIndex = 0;
    			gRID_IDComboBox.DisplayMemberPath="GRID_ID";
    		}
    

     

    Query:

    private System.Data.Objects.ObjectQuery<TABLE1> GetTABLE1Query(MyModelContainer myModelContainer)
    		{
    			
    			System.Data.Objects.ObjectQuery<WpfApplication1.TABLE1> tABLE1Query = myModelContainer.TABLE1;//.Where(t1 => t1.GRID_ID == selCmbValue);
    			// Aktualisiert die Abfrage so, dass sie TABLE2-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_1-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_1");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_2-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_2");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_3-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_3");
    			// Gibt eine ObjectQuery zurück.
    			return tABLE1Query;
    		}
    


    And the xaml:

    <Window.Resources>
        <CollectionViewSource x:Key="tABLE1ViewSource" d:DesignSource="{d:DesignInstance my:TABLE1, CreateList=True}" />
        <CollectionViewSource x:Key="tABLE1TABLE2ViewSource" Source="{Binding Path=TABLE2, Source={StaticResource tABLE1ViewSource}}" />
        <CollectionViewSource x:Key="tABLE1TABLE2TABLE3_1ViewSource" Source="{Binding Path=TABLE3_1, Source={StaticResource tABLE1TABLE2ViewSource}}" />
        <CollectionViewSource x:Key="tABLE1TABLE2TABLE3_2ViewSource" Source="{Binding Path=TABLE3_2, Source={StaticResource tABLE1TABLE2ViewSource}}" />
        <CollectionViewSource x:Key="tABLE1TABLE2TABLE3_3ViewSource" Source="{Binding Path=TABLE3_3, Source={StaticResource tABLE1TABLE2ViewSource}}" />
      </Window.Resources>
      <Grid>
        <StackPanel Name="Data" DataContext="{StaticResource tABLE1ViewSource}">
          <StackPanel>
            <Button x:Name="btnAddData" Width="100" Height="30" Content="Add" Click="AddData_Click"/>
            <Button Click="ButtonRefresh_Click" Width="100" Height="30" Content="Refresh"/>
            <Grid HorizontalAlignment="Left" Name="grid1" VerticalAlignment="Top">
              <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto" />
                <ColumnDefinition Width="Auto" />
              </Grid.ColumnDefinitions>
              <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
              </Grid.RowDefinitions>
              <Label Content="GRID ID:" Grid.Column="0" Grid.Row="0" HorizontalAlignment="Left" Margin="3" VerticalAlignment="Center" />
              <ComboBox DisplayMemberPath="GRID_ID" Foreground="Black" Grid.Column="1" Grid.Row="0" Height="23" HorizontalAlignment="Left" ItemsSource="{Binding Path=GRID_ID, ElementName=Data}" Margin="3" Name="gRID_IDComboBox" VerticalAlignment="Center" Width="120">
                <ComboBox.ItemsPanel>
                  <ItemsPanelTemplate>
                    <VirtualizingStackPanel />
                  </ItemsPanelTemplate>
                </ComboBox.ItemsPanel>
              </ComboBox>
            </Grid>
          </StackPanel>
    
          <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="123" ItemsSource="{Binding}" Name="tABLE1DataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">
            <DataGrid.Columns>
              <DataGridTextColumn x:Name="yEARColumn" Binding="{Binding Path=YEAR}" Header="YEAR" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="gRID_IDColumn" Binding="{Binding Path=GRID_ID}" Header="GRID ID" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="sERIALNUMBERColumn" Binding="{Binding Path=SERIALNUMBER}" Header="SERIALNUMBER" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="sYNC_IDColumn" Binding="{Binding Path=SYNC_ID}" Header="SYNC ID" Width="SizeToHeader" />
            </DataGrid.Columns>
          </DataGrid>
          
          <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="106" ItemsSource="{Binding Source={StaticResource tABLE1TABLE2ViewSource}}" Name="tABLE2DataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">
            <DataGrid.Columns>
              <DataGridTextColumn x:Name="tBL2_SERIALNUMBERColumn" Binding="{Binding Path=TBL2_SERIALNUMBER}" Header="TBL 2 SERIALNUMBER" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="yEARColumn1" Binding="{Binding Path=YEAR}" Header="YEAR" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="gRID_IDColumn1" Binding="{Binding Path=GRID_ID}" Header="GRID ID" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="sERIALNUMBERColumn1" Binding="{Binding Path=SERIALNUMBER}" Header="SERIALNUMBER" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="sYNC_IDColumn1" Binding="{Binding Path=SYNC_ID}" Header="SYNC ID" Width="SizeToHeader" />
            </DataGrid.Columns>
          </DataGrid>
          <StackPanel Orientation="Horizontal">
            
          
          <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="200" ItemsSource="{Binding Source={StaticResource tABLE1TABLE2TABLE3_1ViewSource}}" Name="tABLE3_1DataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">
            <DataGrid.Columns>
              <DataGridTextColumn x:Name="tBL2_SERIALNUMBERColumn1" Binding="{Binding Path=TBL2_SERIALNUMBER}" Header="TBL 2 SERIALNUMBER" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="tBL3_2SERIALNUMBERColumn" Binding="{Binding Path=TBL3_2SERIALNUMBER}" Header="TBL 3 2 SERIALNUMBER" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="yEARColumn2" Binding="{Binding Path=YEAR}" Header="YEAR" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="gRID_IDColumn2" Binding="{Binding Path=GRID_ID}" Header="GRID ID" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="sERIALNUMBERColumn2" Binding="{Binding Path=SERIALNUMBER}" Header="SERIALNUMBER" Width="SizeToHeader" />
              <DataGridTextColumn x:Name="sYNC_IDColumn2" Binding="{Binding Path=SYNC_ID}" Header="SYNC ID" Width="SizeToHeader" />
            </DataGrid.Columns>
          </DataGrid>
            <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="200" ItemsSource="{Binding Source={StaticResource tABLE1TABLE2TABLE3_2ViewSource}}" Name="tABLE3_2DataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">
              <DataGrid.Columns>
                <DataGridTextColumn x:Name="tBL2_SERIALNUMBERColumn2" Binding="{Binding Path=TBL2_SERIALNUMBER}" Header="TBL 2 SERIALNUMBER" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="tBL3_2SERIALNUMBERColumn1" Binding="{Binding Path=TBL3_2SERIALNUMBER}" Header="TBL 3 2 SERIALNUMBER" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="yEARColumn3" Binding="{Binding Path=YEAR}" Header="YEAR" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="gRID_IDColumn3" Binding="{Binding Path=GRID_ID}" Header="GRID ID" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="sERIALNUMBERColumn3" Binding="{Binding Path=SERIALNUMBER}" Header="SERIALNUMBER" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="sYNC_IDColumn3" Binding="{Binding Path=SYNC_ID}" Header="SYNC ID" Width="SizeToHeader" />
              </DataGrid.Columns>
            </DataGrid>
            <DataGrid AutoGenerateColumns="False" EnableRowVirtualization="True" Height="200" ItemsSource="{Binding Source={StaticResource tABLE1TABLE2TABLE3_3ViewSource}}" Name="tABLE3_3DataGrid" RowDetailsVisibilityMode="VisibleWhenSelected" Width="400">
              <DataGrid.Columns>
                <DataGridTextColumn x:Name="tBL2_SERIALNUMBERColumn3" Binding="{Binding Path=TBL2_SERIALNUMBER}" Header="TBL 2 SERIALNUMBER" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="tBL3_3SERIALNUMBERColumn" Binding="{Binding Path=TBL3_3SERIALNUMBER}" Header="TBL 3 3 SERIALNUMBER" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="yEARColumn4" Binding="{Binding Path=YEAR}" Header="YEAR" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="gRID_IDColumn4" Binding="{Binding Path=GRID_ID}" Header="GRID ID" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="sERIALNUMBERColumn4" Binding="{Binding Path=SERIALNUMBER}" Header="SERIALNUMBER" Width="SizeToHeader" />
                <DataGridTextColumn x:Name="sYNC_IDColumn4" Binding="{Binding Path=SYNC_ID}" Header="SYNC ID" Width="SizeToHeader" />
              </DataGrid.Columns>
            </DataGrid>
          </StackPanel>
        </StackPanel>
    

    The ComoxBox loads the data, but I can#t see the data. It's only space.

     

    The Views for the ListViews works fine, but now I want to bind the data to my selection of the combobox.

    As you can see the data for the combobox is loaded as distinct. This is necessary because I only want to see one value record per value.

    best regards

     

    Monday, July 25, 2011 7:42 AM
  • I "solved" it this way...

     

    private void tABLE1ComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
    		{
    			WpfApplication1.MyModelContainer myModelContainer = new WpfApplication1.MyModelContainer();
    			System.Windows.Data.CollectionViewSource tABLE1ViewSource = ((System.Windows.Data.CollectionViewSource)(this.FindResource("tABLE1ViewSource")));
    			System.Data.Objects.ObjectQuery<WpfApplication1.TABLE1> tABLE1Query = this.updateTABLE1Query(myModelContainer);
    			tABLE1ViewSource.Source = tABLE1Query.Execute(System.Data.Objects.MergeOption.AppendOnly);
    		}
    		private System.Data.Objects.ObjectQuery<TABLE1> updateTABLE1Query(MyModelContainer myModelContainer)
    		{
    			var queryCmb = gRID_IDComboBox.SelectedValue;
    
    			System.Data.Objects.ObjectQuery<WpfApplication1.TABLE1> tABLE1Query = myModelContainer.TABLE1.Where("it.GRID_ID = "+queryCmb);
    			// Aktualisiert die Abfrage so, dass sie TABLE2-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_1-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_1");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_2-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_2");
    			// Aktualisiert die Abfrage so, dass sie TABLE3_3-Daten in "TABLE1" enthält. Sie können diesen Code nach Bedarf ändern.
    			tABLE1Query = tABLE1Query.Include("TABLE2.TABLE3_3");
    			// Gibt eine ObjectQuery zurück.
    			return tABLE1Query;
    		}
    


    This works, and that is all I need ;-)

    thanks and best regards

    • Marked as answer by Dru_MS Monday, July 25, 2011 8:28 AM
    Monday, July 25, 2011 8:28 AM