views:

443

answers:

2

I have a custom row template to show some data, and it doesn't use a SelectiveScrollingGrid in its' template. I don't mind handling the events on my outer elements, but I can't seem to figure out how to cause a "Select" behavior. Typically I've been causing it by raising the MouseLeftButtonDownEvent on the active DataGridCell, but now that I don't actually have any DataGridCell's, I'm a bit perplexed on how to duplicate that behavior with only access to the DataGridRow.

+1  A: 

not sure how your template looks like but I guess you can consider selecting the whole row of your grid by setting it's property SelectionUnit="FullRow" and executing the code below; it select the entire row with index 3

int index = 3;
dataGrid.SelectedItem = dataGrid.Items[index];
dataGrid.ScrollIntoView(dataGrid.Items[index]);
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[index]);
row.MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));

if you still want to select a cell, please check if code below would work for you, it selects a cell with index 2 for the row with index 3

int index = 3;
dataGrid.ScrollIntoView(dataGrid.Items[index]);
DataGridRow row = (DataGridRow)dataGrid.ItemContainerGenerator.ContainerFromItem(dataGrid.Items[index]);
if (row != null)
{
    DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(row);
    DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(2);
    if (cell != null)
    {
        cell.IsSelected = true;
        cell.Focus();
    }
}

GetVisualChild procedure implementation:

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;
}

hope this helps, regards

serge_gubenko
Thanks, the first didn't work for me, even though I have FullRow as the selection mode. The second won't work because my template is fully custom and doesn't have a CellsPresenter in it.
thedesertfox
A: 

This is what I ended up getting to work, it's ugly but gets the job done. These elements only highlight upon a left or right click, so I'm having to force a redraw as well, seems ugly to me but it works.

var row = (DataGridRow)((FrameworkElement)sender).TemplatedParent;
var element = (FrameworkElement)sender;
var parentGrid = this.GetGridFromRow((DataGridRow)element.TemplatedParent);
parentGrid.SelectedItems.Clear();
row.IsSelected = true;
element.InvalidateVisual();
parentGrid.UpdateLayout();
thedesertfox