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

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

问题描述

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

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

要访问所选行的控件,将事件 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; 
            }
        }
    }

为了获得所有的项目,我重写了函数 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 + "
";
        }

        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.

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

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