0

The DataGridCell does not appear to be in the VisualTree of controls.

I have a DataGridTemplateColumn that contains a Rectangle and Label in a Stack Panel inside a Grid.

<t:DataGridTemplateColumn>
    <t:DataGridTemplateColumn.CellTemplate>                                
        <DataTemplate>
            <Grid FocusManager.FocusedElement="{Binding ElementName=swatch}">
                <StackPanel Orientation="Horizontal">
                    <Rectangle Name="swatch" PreviewMouseLeftButtonDown="swatch_PreviewMouseLeftButtonDown" />
                    <Label/>
                </StackPanel>
            </Grid>
        </DataTemplate>
    </t:DataGridTemplateColumn.CellTemplate>
</t:DataGridTemplateColumn>

I wanted the PreviewMouseLeftButtonDown event to iterate upwards through the visual tree until it finds the DataGridCell but after the Grid the parent element is null.

private void swatch_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {          
            DataGridCell cell = null;

            while (cell == null)
            {
                cell = sender as DataGridCell;
                sender = ((FrameworkElement)sender).Parent;
            }

            MethodForCell(sender);
        }

Reading the link below it seems that in the DataGrid's Visual tree UIControls are set as the content property of the DataGridCell. So how can I get the DataGridCell from the Rectangle?

http://blogs.msdn.com/b/vinsibal/archive/2008/08/14/wpf-datagrid-dissecting-the-visual-layout.aspx

DanBrum
  • 419
  • 1
  • 7
  • 18

2 Answers2

2

Change your eventhandler on this one:

private void swatch_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {         
            DataGridCell cell = null;

            while (cell == null)
            {
                cell = sender as DataGridCell;
                if (((FrameworkElement)sender).Parent != null)
                    sender = ((FrameworkElement)sender).Parent;
                else 
                    sender = ((FrameworkElement)sender).TemplatedParent;
            }
        }
kmatyaszek
  • 19,016
  • 9
  • 60
  • 65
0

I found this to be much better

public static T GetVisualParent<T>(Visual child) where T : Visual
    {
        T parent = default(T);
        Visual v = (Visual)VisualTreeHelper.GetParent(child);
        if (v == null)
            return null;
        parent = v as T;
        if (parent == null)
        {
            parent = GetVisualParent<T>(v);
        }
        return parent;
    }

And you would call it like this:

var cell = GetVisualParent<DataGridCell>(e.Source);
sergioadh
  • 1,461
  • 1
  • 16
  • 24