Search code examples
c#wpfdata-bindingdatagrid

How to bind datagrid with two itemsSource in WPF?


I have something like this in my xaml

<DataGrid  Name="dgDisplay" >
    <DataGrid.Columns>
          <DataGridTextColumn IsReadOnly="True" x:Name="dgItemCode" Width="100" Header="Barcode" Binding="{Binding ItemCode}" />
           <DataGridTextColumn IsReadOnly="True" x:Name="dgItemName" Width="200" Header="Item Name" Binding="{Binding ItemName}" />
           <DataGridTextColumn IsReadOnly="True" x:Name="dgItemPrice" Width="100" Header="Item Price" Binding="{Binding ItemPrice, StringFormat=RM {0}}" />
           <DataGridTextColumn IsReadOnly="True" x:Name="dgQuantity" Width="150" Header="Quantity" Binding="{Binding Quantity, UpdateSourceTrigger=PropertyChanged}"   />
        </DataGrid.Columns>

      <DataGrid.RowDetailsTemplate >
         <DataTemplate  x:Name="dtItemDisplay"  >
           <StackPanel  Name="spItemDisplay2" HorizontalAlignment="Stretch" Background="White" >
              <Grid>
                <TextBlock Text="Discount: " FontWeight="Bold" Grid.Column="2" Grid.Row="1"/>
                 <TextBox KeyDown="TxtDisc_KeyDown"  x:Name="txtDisc" Text="{Binding Discount, UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Grid.Row="1"/>

                  <DataGrid ItemsSource="{Binding itemSubDisplayList2}" x:Name="dgItemSub">

                                        <DataGrid.Columns>
                                            <DataGridTextColumn Header="item sub" Binding="{Binding ItemIdSub}"/>
                                            <DataGridTextColumn Header="item sub code" Binding="{Binding ItemSubCode}"/>
                                        </DataGrid.Columns>
                                    </DataGrid>
             </Grid>
            </StackPanel>
           </DataTemplate>
          </DataGrid.RowDetailsTemplate>
    </DataGrid>

I have two list or sources that I need to bind in this data grid. for item in datagrid.column and textbox Discount (in RowDetailsTemplate ) its using itemsSource = itemDisplayList meanwhile for item inside 'dgItemSub' its using itemsSource itemSubDisplayList2

the thing is I've this code at my code behind

 dgDisplay.ItemsSource = itemDisplayList;
 dgDisplay.ItemsSource = itemSubDisplayList2;

but it seem like I can't used both. only item that bind to itemSubDisplayList2 works. but if I do not do this it doesn't show any output inside my datagrid.

I've try something like this

  <DataGrid Name="dgDisplay" ItemsSource="{Binding itemDisplayList}">

<DataGrid ItemsSource="{Binding itemSubDisplayList2}" x:Name="dgItemSub"> 

without doing dgDisplay.ItemsSource = itemDisplayList; and dgDisplay.ItemsSource = itemSubDisplayList2; at code behind but it didn't work.

How can I bind from 2 itemsSource in this ?

or is there a way i can access dgItemSub from code behind. like I want to something like this

dgItemSub.ItemsSource = itemSubDisplayList2;

this is how i code the itemDisplayList and itemSubDisplayList2 and I code this at code behind

       ItemDisplay itemDisplay = new ItemDisplay()
                    {
                        ItemCode = item.ItemCode,
                        ItemName = item.ItemName,
                        ItemPrice = item.ItemPrice,
                        Quantity = 1,
                    };

                    itemDisplayList.Add(itemDisplay);


                    foreach (var id in itemIds)
                    {
                        SimpleItem item2 = simpleItemBO.GetItemByItemId(id);
                        itemList.Add(item2);

                        ItemSubDisplay itemSubDisplay = new ItemSubDisplay();
                        itemSubDisplay.ItemIdSub = item2.ItemId;
                      itemSubDisplay.ItemSubCode = item2.ItemCode;
                        itemSubDisplayList.Add(itemSubDisplay);
                    }

                    itemSubDisplayList2.AddRange(itemSubDisplayList);

Solution

  • Hello I check this code and here u have done some mistakes so i modified it Xaml

     <DataGrid  Name="dgDisplay" AutoGenerateColumns="False" CanUserAddRows="False" >
                <DataGrid.Columns>
                    <DataGridTextColumn IsReadOnly="True" x:Name="dgItemCode" Width="100" Header="Barcode" Binding="{Binding ItemCode}" />
                    <DataGridTextColumn IsReadOnly="True" x:Name="dgItemName" Width="200" Header="Item Name" Binding="{Binding ItemName}" />
                    <DataGridTextColumn IsReadOnly="True" x:Name="dgItemPrice" Width="100" Header="Item Price" Binding="{Binding ItemPrice, StringFormat=RM {0}}" />
                    <DataGridTextColumn IsReadOnly="True" x:Name="dgQuantity" Width="150" Header="Quantity" Binding="{Binding Quantity, UpdateSourceTrigger=PropertyChanged}"   />
                </DataGrid.Columns>
    
                <DataGrid.RowDetailsTemplate >
                    <DataTemplate  x:Name="dtItemDisplay"  >
                        <StackPanel  Name="spItemDisplay2" HorizontalAlignment="Stretch" Background="White" >
                            <Grid>
                                <TextBlock Text="Discount: " FontWeight="Bold" Grid.Column="2" Grid.Row="1"/>
                                <TextBox   x:Name="txtDisc" Text="{Binding Discount, UpdateSourceTrigger=PropertyChanged}" Grid.Column="3" Grid.Row="1"/>
    
                                <DataGrid ItemsSource="{Binding itemSubDisplayList}" x:Name="dgItemSub" AutoGenerateColumns="False"  CanUserAddRows="False">
    
                                    <DataGrid.Columns>
                                        <DataGridTextColumn Header="item sub" Binding="{Binding ItemIdSub}"/>
                                        <DataGridTextColumn Header="item sub code" Binding="{Binding ItemSubCode}"/>
                                    </DataGrid.Columns>
                                </DataGrid>
                            </Grid>
                        </StackPanel>
                    </DataTemplate>
                </DataGrid.RowDetailsTemplate>
            </DataGrid>
    

    Code

       public partial class MainWindow : Window
            {
        
                public List<ItemDisplay> itemDisplayList { get; set; }
        
                public MainWindow()
                {
                    InitializeComponent();
        
                    this.DataContext = this;
        
                    itemDisplayList = new List<ItemDisplay>();
                    ItemDisplay itemDisplay = new ItemDisplay()
                    {
                        ItemCode = "1",
                        ItemName = "1",
                        ItemPrice = "1",
                        Quantity = "1",
                        itemSubDisplayList = new List<ItemSub>()
                    };
                    itemDisplay.itemSubDisplayList.Add(new ItemSub { ItemIdSub = "sa", ItemSubCode = "ran" });
                    itemDisplayList.Add(itemDisplay);
        
                    dgDisplay.ItemsSource = itemDisplayList;
        
                }
    
    
      public class ItemDisplay
        {
            public string ItemCode { get; set; }
            public string ItemPrice { get; set; }
            public string ItemName { get; set; }
            public string Quantity { get; set; }
            public List<ItemSub> itemSubDisplayList { get; set; }
        }
    
    
        public class ItemSub
        {
            public string ItemIdSub { get; set; }
            public string ItemSubCode { get; set; }
        }
    

    output Output ss