简体   繁体   English

如何获取DataGridTemplateColumn的底层(TextBox)控件

[英]How to get the underlying (TextBox) Control of a DataGridTemplateColumn

I use this code to add a TextBox to a DataGrid cell: (no, I can't use XAML here) 我使用此代码将TextBox添加到DataGrid单元格:(不,我不能在这里使用XAML)

Binding binding = new Binding("Fld_Company");
binding.Mode = BindingMode.OneWay;

FrameworkElementFactory frameworkElementFactory = new FrameworkElementFactory(typeof(TextBox));
DataTemplate dataTemplate = new DataTemplate();
dataTemplate.VisualTree = frameworkElementFactory;
frameworkElementFactory.SetBinding(TextBox.TextProperty, binding);

DataGridTemplateColumn dataGridTemplateColumn = new DataGridTemplateColumn();
dataGridTemplateColumn.IsReadOnly = true;
dataGridTemplateColumn.Header = "Company";
dataGridTemplateColumn.CellTemplate = dataTemplate;

this.dataGrid.Columns.Add(dataGridTemplateColumn);

I there a way to get the underlying TextBox control without XAML? 我有办法在没有XAML的情况下获得基础TextBox控件吗?

What I tried: 我尝试了什么:

  • VisualTreeHelper, but the GetChildrenCount() is always 0 VisualTreeHelper,但GetChildrenCount()始终为0
  • FindName, but I haven't found a proper FrameworkElement FindName,但我还没有找到合适的FrameworkElement

After explored the DataGrid for a while I see that my question does not make any sense. 在探索了DataGrid一段时间后,我发现我的问题没有任何意义。 My code above prepares just the DataGrid but does not fill any data. 我上面的代码只准备DataGrid但不填充任何数据。 Until that no rows are generated and therefore no underlying TextBox controls can be found. 直到没有生成行,因此找不到underlying TextBox controls

When the DataGrid gets finally filled with data, the best way to get the underlying controls seems to be catching the LoadinRow event. 当DataGrid最终填充数据时,获取底层控件的最佳方法似乎是捕获LoadinRow事件。 But when this event fires, the loading of the row is not finished. 但是当此事件触发时,行的加载未完成。 There needs to be temporarily assigned a second event which fires when the row is finally loaded. 需要临时分配第二个事件,该事件在最终加载行时触发。

{
    DataGrid.LoadingRow += DataGrid_LoadingRow;
}

private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
{
    // The visual tree is not built until the row is "loaded". This event fires when this happend:
    e.Row.Loaded += DataGrid_Row_Loaded;
}

private void DataGrid_Row_Loaded(object sender, RoutedEventArgs e)
{
    DataGridRow dataGridRow = (DataGridRow)sender;
    // important: Remove the event again
    dataGridRow.Loaded -= DataGrid_Row_Loaded;

    NestedGridFieldProperty ngrProp = (NestedGridFieldProperty)dataGridRow.Item;

    // Get the "presenter", which contains the cells
    DataGridCellsPresenter presenter = coNeboTools.ConeboMisc.GetVisualChild<DataGridCellsPresenter>(dataGridRow);

    // Get the cells in the presenter
    var cells = GetVisualChildren<DataGridCell>(presenter);

    // Get the underlying TextBox in column 0
    TextBox underlyingTextBox = (TextBox)cells.ElementAt(0).Content;

    // the Item property of the row contains the row data
    var myData = dataGridRow.Item;

    // do what ever is needed with the TextBlock
    underlyingTextBox.Foreground = Brushes.Red;
}

    // Static helper method to handle the visual tree
    public static IEnumerable<T> GetVisualChildren<T>(DependencyObject dependencyObject)
           where T : DependencyObject
    {
        if (dependencyObject != null)
        {
            int childrenCount = VisualTreeHelper.GetChildrenCount(dependencyObject);

            for (int i = 0; i < childrenCount; i++)
            {
                DependencyObject child = VisualTreeHelper.GetChild(dependencyObject, i);
                if (child != null && child is T)
                {
                    yield return (T)child;
                }

                foreach (T childOfChild in GetVisualChildren<T>(child))
                {
                    yield return childOfChild;
                }
            }
        }
    }

    // Static helper method to handle the visual tree
    public static childItem GetVisualChild<childItem>(DependencyObject obj)
        where childItem : DependencyObject
    {
        foreach (childItem child in GetVisualChildren<childItem>(obj))
        {
            return child;
        }

        return null;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM