I have requirement on Nested datagrid in WPF. Parent Grid Shown Order information of Consumers.When User click the details in order information, need to be displayed ordered items details in child datagrid(Means Nested grid) within the parent row of order information. I need to populate the multiple nested datagrids
For first row on click Edit Button I am getting related child grid. Second row on wards the output i am getting is a empty datagrid. If I debug data is binding using ItemSource but its not displaying in child grid.
For this i am using to bind child datagrid. My XAML code is as follows.
<Popup Name="popup1" IsOpen="False" Placement="Mouse" Height="500" Width="700">
<Border BorderBrush="Black" BorderThickness="1" Background="White">
<StackPanel Orientation="Horizontal">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<DataGrid Grid.Row="0" Grid.Column="0" SelectedValuePath="orderid"
AutoGenerateColumns="False" Height="350"
HorizontalAlignment="Left" Margin="114,128,0,0" x:Name="gridOrder" VerticalAlignment="Top" Width="500">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Order Status">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Button Content="{Binding OrderStatus}" Click="EditButton_Click" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Full Name" Binding="{Binding fullname}" />
<DataGridTextColumn Header="Order ID" Binding="{Binding orderid}" />
<DataGridTextColumn Header="Mobile" Binding="{Binding mobile}" />
<DataGridTextColumn Header="No. of Items" Binding="{Binding countofItems}" />
<DataGridTextColumn Header="Total Price" Binding="{Binding Total_Price}" />
<DataGridTextColumn Header="Order Status" Binding="{Binding OrderStatus}" />
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<DataGrid x:Name="gridOrderDetails" AutoGenerateColumns="False"
Height="200" HorizontalAlignment="Left" Margin="121,132,0,0" VerticalAlignment="Top" Width="200">
<DataGrid.Columns>
<DataGridTextColumn Header="Item ID" Binding="{Binding itemid}" />
<DataGridTextColumn Header="Item Name" Binding="{Binding ItemName}" />
<DataGridTextColumn Header="Item No." Binding="{Binding ItemNo}" />
<DataGridTextColumn Header="Quantity" Binding="{Binding quantity}" />
<DataGridTextColumn Header="Comments" Binding="{Binding comments}" />
<DataGridTextColumn Header="Item Price" Binding="{Binding ItemPrice}" />
<DataGridTextColumn Header="Quantity" Binding="{Binding quantity}" />
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
<Button Content="Close" Grid.Row="1" Grid.Column="1" Click="PopUp_OK_Click"/>
</Grid>
</StackPanel>
</Border>
</Popup>
My C# code is as follows:
private void EditButton_Click(object sender, RoutedEventArgs e)
{
try
{
DBDataContext dbContext = new DBDataContext();
SP_Get_OrderItemResult orderRow = gridOrder.SelectedItem as SP_Get_OrderItemResult;
DataGrid grid = FindChild<DataGrid>(gridOrder, "gridOrderDetails");
grid.ItemsSource = dbContext.SP_Get_ItemList(orderRow.orderid);
}
catch (Exception Ex)
{
MessageBox.Show(Ex.Message);
return;
}
}
/// <summary>
/// Finds a Child of a given item in the visual tree.
/// </summary>
/// <param name="parent">A direct parent of the queried item.</param>
/// <typeparam name="T">The type of the queried item.</typeparam>
/// <param name="childName">x:Name or Name of child. </param>
/// <returns>The first parent item that matches the submitted type parameter.
/// If not matching item can be found,
/// a null parent is being returned.</returns>
public static T FindChild<T>(DependencyObject parent, string childName)
where T : DependencyObject
{
// Confirm parent and childName are valid.
if (parent == null) return null;
T foundChild = null;
int childrenCount = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < childrenCount; i++)
{
var child = VisualTreeHelper.GetChild(parent, i);
// If the child is not of the request child type child
T childType = child as T;
if (childType == null)
{
// recursively drill down the tree
foundChild = FindChild<T>(child, childName);
// If the child is found, break so we do not overwrite the found child.
if (foundChild != null) break;
}
else if (!string.IsNullOrEmpty(childName))
{
var frameworkElement = child as FrameworkElement;
// If the child's name is set for search
if (frameworkElement != null && frameworkElement.Name == childName)
{
// if the child's name is of the request name
foundChild = (T)child;
break;
}
}
else
{
// child element found.
foundChild = (T)child;
break;
}
}
return foundChild;
}