Как получить базовый (TextBox) элемент управления DataGridTemplateColumn - PullRequest
0 голосов
/ 31 мая 2019

Я использую этот код для добавления 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);

Есть ли способ получить базовый элемент управления TextBox без XAML?

Что я пробовал:

  • VisualTreeHelper, но GetChildrenCount () всегда равен 0
  • FindName, но я не нашел правильного FrameworkElement

1 Ответ

0 голосов
/ 22 июня 2019

После некоторого изучения DataGrid я вижу, что мой вопрос не имеет никакого смысла. Мой код выше готовит только DataGrid, но не заполняет никаких данных. До этого строки не генерируются и, следовательно, underlying TextBox controls не может быть найдено.

Когда DataGrid наконец-то заполняется данными, лучший способ получить базовые элементы управления - это перехват события LoadinRow. Но когда происходит это событие, загрузка строки не заканчивается. Необходимо временно назначить второе событие, которое запускается, когда строка наконец загружается.

{
    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;
    }
...