none
Grabing controls from a DataGrid

    Question

  • I'm using the new release of the DataGrid from the WPF toolkit, and I wanted to know if there's a way to get a control out of a populated data grid.  Lets say, for example, want to allow users to check multiple items in the grid, so I supply a checkbox like so:
    <tool:DataGrid x:Name="dgParameters" DataContext="{Binding Path=EventNode}"
      <tool:DataGrid.Columns> 
        <tool:DataGridTemplateColumn> 
          <tool:DataGridTemplateColumn.CellTemplate> 
            <DataTemplate> 
              <CheckBox x:Name="chkSelected" /> 
            </DataTemplate> 
          </tool:DataGridTemplateColumn.CellTemplate> 
        </tool:DataGridTemplateColumn> 
        <!-- ... --> 
      </tool:DataGrid.Columns> 
    <tool:/DataGrid> 

    Then I supply a button at the bottom with an event that alows you to delete all the checked items.  Is there a way I can itterate through those controls to see if they're checked?  Something similar to...

    foreach( ? cell in dgParameters.? ) 
       CheckBox box = (CheckBox)cell.getControl("chkSelected"); 
       if(box.Checked) 
         // Delete the time? 

    Thursday, August 21, 2008 10:55 PM

Answers

  •  You can do something like this:

    foreach(DataGridColumn column in DataGrid.Columns)
    {
        FrameworkElement fe = column.GetCellContent(DataGrid.Items[i]);
    }

    If you want to get the Cell or Row visual you can do something like this:

    public DataGridCell GetCell(int row, int column)
    {
        DataGridRow rowContainer = GetRow(row);

        if
    (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                // now try to bring into view and retreive the cell
                DataGrid_Standard.ScrollIntoView(rowContainer, DataGrid_Standard.Columns[column]);
                cell = (
    DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }

    public DataGridRow GetRow(int index)
    {
        DataGridRow row = (DataGridRow)DataGrid_Standard.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            // may be virtualized, bring into view and try again
            DataGrid_Standard.ScrollIntoView(DataGrid_Standard.Items[index]);
            row = (
    DataGridRow)DataGrid_Standard.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }

    I wrote a sample here that may help, http://blogs.msdn.com/vinsibal/archive/2008/08/11/net-3-5-sp1-and-wpf-datagrid-ctp-is-out-now.aspx

    • Marked as answer by fuzzybinary Friday, August 22, 2008 3:45 PM
    Friday, August 22, 2008 7:22 AM

All replies

  •  You can do something like this:

    foreach(DataGridColumn column in DataGrid.Columns)
    {
        FrameworkElement fe = column.GetCellContent(DataGrid.Items[i]);
    }

    If you want to get the Cell or Row visual you can do something like this:

    public DataGridCell GetCell(int row, int column)
    {
        DataGridRow rowContainer = GetRow(row);

        if
    (rowContainer != null)
        {
            DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);

            // try to get the cell but it may possibly be virtualized
            DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            if (cell == null)
            {
                // now try to bring into view and retreive the cell
                DataGrid_Standard.ScrollIntoView(rowContainer, DataGrid_Standard.Columns[column]);
                cell = (
    DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
            }
            return cell;
        }
        return null;
    }

    public DataGridRow GetRow(int index)
    {
        DataGridRow row = (DataGridRow)DataGrid_Standard.ItemContainerGenerator.ContainerFromIndex(index);
        if (row == null)
        {
            // may be virtualized, bring into view and try again
            DataGrid_Standard.ScrollIntoView(DataGrid_Standard.Items[index]);
            row = (
    DataGridRow)DataGrid_Standard.ItemContainerGenerator.ContainerFromIndex(index);
        }
        return row;
    }

    I wrote a sample here that may help, http://blogs.msdn.com/vinsibal/archive/2008/08/11/net-3-5-sp1-and-wpf-datagrid-ctp-is-out-now.aspx

    • Marked as answer by fuzzybinary Friday, August 22, 2008 3:45 PM
    Friday, August 22, 2008 7:22 AM
  • Yeah that seems to work.  Sad that I have to know which particular column holds the control though, but I'm sure it's unavoidable.
    Friday, August 22, 2008 3:45 PM
  • Hi,
    We are trying to get a styled WPF Toolkit Datagrid (not the windows forms datagrid).

    I've searched the web and everything I've found suggests you take control of the cell style by utilising the loadingrow function and then getting the datagridcell.

    Our grid is dynamically build from a datatable as we want to re-use the same style / colouring in several programs. The problem is the code...

    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row1);

    always returns null as does either of the following...

    FrameworkElement fex = colz.GetCellContent(dgrid2.Items[z2]);
    FrameworkElement fe3 = col3.GetCellContent(row1);

    where row1 is defined by;

    DataGridRow row1 = (DataGridRow)dgrid2.ItemContainerGenerator.ContainerFromIndex(z2);

    I feel this should be straightforward, but so far most things suggest hard-coding the column names and driving the style from however many converters are needed.

    I can supply an example program showing the problem if needed, this is really stopping us from moving forward, which is frustrating as the answer seems just out of reach.

    If anyone can help I'd be extremely grateful.

    -Colin H
    Thursday, February 12, 2009 11:18 AM
  • Can some1 please tell me about the GetVisualChild<DataGridCellsPresenter>..

    Regards,

    Bilal Rehman
    Tuesday, March 24, 2009 3:46 PM
  • I found it here http://wpf.codeplex.com/Thread/View.aspx?ThreadId=34065

     

    static T GetVisualChild<T>(Visual parent) where T : Visual
    {
        T child =
    default(T);
        int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
        for (int i = 0; i < numVisuals; i++)
        {
            Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
            child = v
    as T;
            if (child == null)
            {
                child = GetVisualChild<T>(v);
            }
            if (child != null)
            {
                break;
            }
        }
        return child;
    }

    Sunday, April 25, 2010 2:37 PM
  • I know it's been forever but i just debugged through this GetCellContent() always null issue on my WPF project and it wound up being that applying DataGrid.Items.SortDescription's made this start happening... unfortunately even if i move the GetCellContent() logic prior to the sorting, the sorting would blow away whatever modifications i did to the cell content :(

    So i wound up applying the sorting on the underlying DataView's rather than the DataGrid.Items.SortDescription.

    fyi, all my source (WPF4 LOB): http://code.google.com/p/itraacv2/source/browse/#svn%2Ftrunk%2FApp

    ...\Views\tabSponsor.xaml.cs is where this is going on



    Monday, June 20, 2011 10:18 PM
  • sir, 

    I get the issue of Cell= null , I get the Exception

    Thursday, October 18, 2012 2:12 AM