Question

I have a datagrid say Datagrid1 that is populated with a List (Dynamically through code behind). Inside the row details template for datagrid , i want to add a datagrid, lets calls it datagrid2, the datagrid2 needs to dynamically poupulated with List on the SelectionChange event of Datagrid1 ? Accessing the datagrid2 and binding it to a datasource needs to be done in the code behind. Can somone help me out with this? my xaml is:

<Grid>
        <my:DataGrid    Name="dataGrid1" ItemsSource="{Binding}">
            <my:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <my:DataGrid Name="dataGrid2"></my:DataGrid>
                </DataTemplate>
            </my:DataGrid.RowDetailsTemplate>
        </my:DataGrid>
    </Grid>
Was it helpful?

Solution

It would be much easier to do it via bindings. You could add a collection of DetailElements to each Element of your dataGrid1's ItemsSource. Now all you have to do is binding this collection to your dataGrid2' ItemsSource and it gets automatically populated with data through the binding.

public class DataGrid1SourceItem
{
    public ObservableCollection<DetailItem> DetailItems {get;set;}
}

The XAML:

<Grid>
    <my:DataGrid    Name="dataGrid1" ItemsSource="{Binding}">
        <my:DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <my:DataGrid Name="dataGrid2" ItemsSource="{Binding Path=DetailItems}"></my:DataGrid>
            </DataTemplate>
        </my:DataGrid.RowDetailsTemplate>
    </my:DataGrid>
</Grid>  

EDIT: To search your database depending on the DataGrid cells value, you have to get this value into your ViewModel. To do this create a property (in my example ProductName) and bind it to the DataGridColumn's Binding property (Mode=TwoWay). Then you could have a private field which holds all products and filter this field in the dataGrid2 ItemsSources collection:

public class DataGrid1SourceItem
{
    private List<DetailItems> _allDetailItems = new List<DetailItems>();
    public IEnumerable<DetailItem> DetailItems 
    {
       get { return _allDetailItems.Where(item => item.Name == ProductName); }
    } 

    public DataGrid1SourceItem()
    {
       // load your products into _allDetailItems
    }

    private string _productName;
    public string ProductName
    {
        get { return _productName; }
        set
        {
            _productName= value;
            OnPropertyChanged("ProductName");
            OnPropertyChanged("DetailItems");
        }
    }
}

OTHER TIPS

Following may help you

public partial class Window1 : Window
    {
        DataTable dt = new DataTable();
        public Window1()
        {
            InitializeComponent();
            dt.Columns.Add("Num1", typeof(string));
            dt.Columns.Add("Num2", typeof(string));
            dt.Rows.Add("100", "200");
            dt.Rows.Add("300", "400");
            this.dataGridTest.DataContext = dt;
            this.dataGridTest.RowDetailsVisibilityChanged += new EventHandler<Microsoft.Windows.Controls.DataGridRowDetailsEventArgs>(dataGridTest_RowDetailsVisibilityChanged);
        }
        void dataGrid1_RowDetailsVisibilityChanged(object sender, Microsoft.Windows.Controls.DataGridRowDetailsEventArgs e)
        {
            Microsoft.Windows.Controls.DataGrid  innerDataGrid = e.DetailsElement as Microsoft.Windows.Controls.DataGrid;
            innerDataGrid.ItemsSource = ((IListSource)dt).GetList();
        }
    }

In XAML

<Grid>
        <my:DataGrid  Name="dataGridTest" ItemsSource="{Binding}">
            <my:DataGrid.RowDetailsTemplate>
                <DataTemplate>
                    <my:DataGrid Name="innerGrid"></my:DataGrid>
                </DataTemplate>
            </my:DataGrid.RowDetailsTemplate>
        </my:DataGrid>
    </Grid>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top