在运行时访问WPF工具包DataGridCell的DataTemplate控件,如何?

发布于 2024-08-09 17:35:15 字数 2526 浏览 8 评论 0 原文

我有一个使用 WPF Toolkit 定义的 DataGrid。此 DataGrid 的 CellEditingTemplate 在运行时与构建 FrameworkElementFactory 元素的自定义函数关联。

现在我必须访问插入到 CellEditingTempleta 的 DataTemplate 中的控件,但我不知道该怎么做。

在网络上,我发现了一个有用的 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;
    }
}

此代码适用于 ListView 对象,但不适用于 DataGrid 对象。

如何在 DataGrid 中使用这样的东西?

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

孤城病女 2024-08-16 17:35:15

好吧,但我用这段代码创建了一个 DataTemplate...

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

并且我需要像控制对象一样管理 txtStandard;如何将 FrameworkElementFactory 转换为 Control?

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?

七颜 2024-08-16 17:35:15

新想法:
不要在 DataTemplate 中创建文本对象,而是创建您创建的自定义控件的实例。然后将文本对象放入自定义控件中,并将管理它所需的所有代码放入自定义控件中。

旧想法:
您将需要递归访问 DataGrid 的 VisualTree。我建议您在运行时使用 Snoop 等程序监视您的应用程序,然后编辑您的示例代码提供沿着正确的路径到达您感兴趣的控件。

请记住,这很困难,因为它不是常见的工作流程。您可能应该在 DataTemplate 中创建绑定。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文