如何访问datagrid模板列文本框文本WPF C# [英] How to access datagrid template column textbox text WPF C#

查看:123
本文介绍了如何访问datagrid模板列文本框文本WPF C#的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要从代码后面的 DataGrid 的模板列中访问文本,但我不知道如何。我需要将文本更改为 SelectionChanged 事件中传递给我的任何字符串。有人可以告诉我如何实现吗?我发现一个类似的问题这里
,但没有答案。

I need to access the text in a DataGrid's template column from code behind, but I don't know how. I need to change the text to whatever string I pass to it on the SelectionChanged event. Can someone please tell me how to achieve this? I found a similar question here but it had no answers.

推荐答案

DataGrid中找到控件模板列,您应该使用 FindChild()

To find a control in a DataGrid template column, you should use FindChild():

    public static T FindChild<T>(DependencyObject parent, string childName) where T : DependencyObject
    {
        if (parent == null)
        {
            return null;
        }

        T foundChild = null;

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

        for (int i = 0; i < childrenCount; i++)
        {
            var child = VisualTreeHelper.GetChild(parent, i);
            T childType = child as T;

            if (childType == null)
            {
                foundChild = FindChild<T>(child, childName);

                if (foundChild != null) break;
            }
            else
                if (!string.IsNullOrEmpty(childName))
                {
                    var frameworkElement = child as FrameworkElement;

                    if (frameworkElement != null && frameworkElement.Name == childName)
                    {
                        foundChild = (T)child;
                        break;
                    }
                    else
                    {
                        foundChild = FindChild<T>(child, childName);

                        if (foundChild != null)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    foundChild = (T)child;
                    break;
                }
        }

        return foundChild;
    }

例如我在 MyDataGrid 中有这个模板列:

For example I have this template column in MyDataGrid:

<DataGridTemplateColumn Width="1.5*" IsReadOnly="False">
    <DataGridTemplateColumn.Header>
        <TextBlock Text="Sample" ToolTip="{Binding Path=Text, RelativeSource={RelativeSource Self}}" FontSize="14" />
     </DataGridTemplateColumn.Header>

     <DataGridTemplateColumn.CellTemplate>
         <DataTemplate>
             <TextBlock x:Name="MyTextBlock" Text="Hello!" />
         </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

从代码中访问它,您可以:

Access it from the code, you can:

TextBlock MyTextBlock = FindChild<TextBlock>(MyDataGrid, "MyTextBlock");

MessageBox.Show(MyTextBlock.Text);

注意:只有当控件完全加载时,始终使用FindChild,否则不会找到它并给出null。在这种情况下,我将此代码放在事件 ContentRendered (Window)中,表示窗口的所有内容都成功加载(即使事件MyDataGrid_Loaded无法访问MyTextBlock,因为尚未加载):

Note: Always use FindChild only when the control will be fully loaded, otherwise it will not find it and give null. In this case, I put this code in the event ContentRendered (Window) which says that all the contents of the window successfully load (even the event MyDataGrid_Loaded not have access to MyTextBlock, because it is not yet loaded):

    private void Window_ContentRendered(object sender, EventArgs e)
    {
        TextBlock MyTextBlock = FindChild<TextBlock>(MyDataGrid, "MyTextBlock");

        MessageBox.Show(MyTextBlock.Text);
    }

EDIT1:

要访问所选行的控件以将事件 SelectionChanged 添加到要强制运行的 DataGrid ,这将给出选定的行:

To access the control of selected row to add event SelectionChanged to DataGrid in which to function, which will give a selected row:

    private void MyDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e)
    {
        try
        {
            var row_list = GetDataGridRows(MyDataGrid);

            foreach (DataGridRow single_row in row_list)
            {
                if (single_row.IsSelected == true)
                {
                    TextBlock MyTextBlock = FindChild<TextBlock>(single_row, "MyTextBlock");

                    MessageBox.Show(MyTextBlock.Text);
                }
            }
        }

        catch 
        {
            throw new Exception("Can't get access to DataGridRow");
        }
    }

GetDataGridRows()的列表:

Listing of GetDataGridRows():

    public IEnumerable<DataGridRow> GetDataGridRows(DataGrid grid)
    {
        var itemsSource = grid.ItemsSource as IEnumerable;

        if (null == itemsSource)
        {
            yield return null; 
        }

        foreach (var item in itemsSource)
        {
            var row = grid.ItemContainerGenerator.ContainerFromItem(item) as DataGridRow;

            if (null != row)
            {
                yield return row; 
            }
        }
    }

EDIT2: / strong>

要获取所有项目,我重写了函数FindChild():

To get ALL the items I rewrote the function FindChild():

    public static void FindChildGroup<T>(DependencyObject parent, string childName, ref List<T> list) where T : DependencyObject
    {
        // Checks should be made, but preferably one time before calling.
        // And here it is assumed that the programmer has taken into
        // account all of these conditions and checks are not needed.
        //if ((parent == null) || (childName == null) || (<Type T is not inheritable from FrameworkElement>))
        //{
        //    return;
        //}

        int childrenCount = VisualTreeHelper.GetChildrenCount(parent);

        for (int i = 0; i < childrenCount; i++)
        {
            // Get the child
            var child = VisualTreeHelper.GetChild(parent, i);

            // Compare on conformity the type
            T child_Test = child as T;

            // Not compare - go next
            if (child_Test == null)
            {
                // Go the deep
                FindChildGroup<T>(child, childName, ref list);
            }
            else
            {
                // If match, then check the name of the item
                FrameworkElement child_Element = child_Test as FrameworkElement;

                if (child_Element.Name == childName)
                {
                    // Found
                    list.Add(child_Test);
                }

                // We are looking for further, perhaps there are
                // children with the same name
                FindChildGroup<T>(child, childName, ref list);
            }
        }

        return;
    }

调用此新功能:

   private void Window_ContentRendered(object sender, EventArgs e)
   {
        // Create the List
        List<TextBlock> list = new List<TextBlock>();

        // Find all elements
        FindChildGroup<TextBlock>(MyDataGrid, "MyTextBlock", ref list);
        string text = "";

        // Print
        foreach (TextBlock elem in list)
        {
            text += elem.Text + "\n";
        }

        MessageBox.Show(text, "Text in TextBlock");
   }

一般来说,这种做法不是最好的...获取项目例如全部或所选),您可以直接联系到存储数据的列表(如 ObservableCollection )。此外,它是有用的事件,例如 PropertyChanged

Generally, this practice is not the best ... to get the items (such as all or selected), you can contact directly to the list which stores your data (like ObservableCollection). Also, it is useful events such as PropertyChanged.

这篇关于如何访问datagrid模板列文本框文本WPF C#的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆