views:

785

answers:

2

I have a DataGrid defined with WPF Toolkit. The CellEditingTemplate of this DataGrid is associated at runtime with a custom function that build a FrameworkElementFactory element.

Now I have to access to control that is inserted inside DataTemplate of CellEditingTempleta, but I do not know how to do.

On web I found a useful ListView Helper...

public static class ListViewHelper
{
    public static FrameworkElement GetElementFromCellTemplate(ListView listView, Int32 column, Int32 row, String name)
    {
        if (row >= listView.Items.Count || row < 0)
        {
            throw new ArgumentOutOfRangeException("row");
        }

        GridView gridView = listView.View as GridView;
        if (gridView == null)
        {
            return null;
        }

        if (column >= gridView.Columns.Count || column < 0)
        {
            throw new ArgumentOutOfRangeException("column");
        }

        ListViewItem item = listView.ItemContainerGenerator.ContainerFromItem(listView.Items[row]) as ListViewItem;
        if (item != null)
        {
            GridViewRowPresenter rowPresenter = GetFrameworkElementByName<GridViewRowPresenter>(item);
            if (rowPresenter != null)
            {
                ContentPresenter templatedParent = VisualTreeHelper.GetChild(rowPresenter, column) as ContentPresenter;
                DataTemplate dataTemplate = gridView.Columns[column].CellTemplate;
                if (dataTemplate != null && templatedParent != null)
                {
                    return dataTemplate.FindName(name, templatedParent) as FrameworkElement;
                }
            }
        }

        return null;
    }

    private static T GetFrameworkElementByName<T>(FrameworkElement referenceElement) where T : FrameworkElement
    {
        FrameworkElement child = null;
        for (Int32 i = 0; i < VisualTreeHelper.GetChildrenCount(referenceElement); i++)
        {
            child = VisualTreeHelper.GetChild(referenceElement, i) as FrameworkElement;
            System.Diagnostics.Debug.WriteLine(child);
            if (child != null && child.GetType() == typeof(T))
            {
                break;
            }
            else if (child != null)
            {
                child = GetFrameworkElementByName<T>(child);
                if (child != null && child.GetType() == typeof(T))
                {
                    break;
                }
            }
        }
        return child as T;
    }
}

this code work with the ListView object but not with the DataGrid object.

How can use something like this in DataGrid?

A: 

New Idea: Instead of creating a text object in the DataTemplate, create an instance of a custom control you create. Then put the text object in your custom control and put all the code you need to manage it in the custom control.

Old Idea: You will need to recurse through the DataGrid's VisualTree. I recommend you spy on your app at run time with a program such as Snoop and then edit the sample code you provided to travel down the correct path to the control you are interested in.

Keep in mind that this is hard because it is not a common workflow. You should probably be creating bindings in your DataTemplate instead.

vanja.
A: 

Well, but I created a DataTemplate with this code...

var txtStandard = new FrameworkElementFactory(typeof(TextBox)); txtStandard.SetBinding(TextBox.TextProperty, new Binding("Entity")); new DataTemplate { VisualTree = txtStandard };

and I need to manage the txtStandard like a Control object; how can cast a FrameworkElementFactory to Control?

LukePet
You can't cast it to a control. Why do you need to access it as a control object? You could give it a unique control.Tag and then search the visual tree for an object with that tag, but thats awful too. You are binding to the Text property, why don't you bind the other properties too?
vanja.