wpf принудительно построить визуальное дерево

У меня есть ItemsControl с сеткой как ItemsPanelTemplate

<ItemsControl ItemsSource="{Binding CellCollection}" Name="CellGrid">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <Grid Name="grid" />
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

Я создаю некоторый UserControl с этим ItemControl внутри в программном коде, а затем мне нужно создать RowDefinitions и ColumnDefinitons. Я использую этот метод для получения «сетки»:

private TChildItem FindVisualChild<TChildItem>(DependencyObject obj) where TChildItem : DependencyObject
    {
        for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++)
        {
            var child = VisualTreeHelper.GetChild(obj, i);

            if (child != null && child is TChildItem)
                return (TChildItem)child;

            var childOfChild = FindVisualChild<TChildItem>(child);

            if (childOfChild != null)
                return childOfChild;
        }

        return null;
    }

Но если я вызову этот метод перед отображением UserControl, он вернет null, поэтому я не могу найти «сетку» доступа, а когда появляется UserControl, он отображается не так, как я ожидал.

Я пытался гуглить, но все, что я нашел, это предположение, что VisualTree не строится для ItemControl, пока он не отобразится в форме.

Какие-либо предложения? Спасибо и извините за плохой английский ;)


person user1308583    schedule 26.05.2012    source источник


Ответы (1)


Вы можете вызвать ApplyTemplate, чтобы элемент применил шаблон и построить визуальное дерево.

Хотя это не применяет шаблоны полностью. В этом случае вам сначала нужно будет вызвать ApplyTemplate() в ItemsControl, затем var item_presenter = FindVisualChild<ItemsPresenter>(items_control), затем вам нужно вызвать item_presenter.ApplyTemplate(), и теперь вы принудительно поместите Grid в VisualTree.

person Steve    schedule 26.05.2012
comment
хм, нет, не работает, FindVisualChild() по-прежнему возвращает null. Помогает только отображение UseControl и только затем обновление определений строк и столбцов. - person user1308583; 27.05.2012
comment
На каком этапе вы звоните FindVisualChild? Строительство, Грузится, что-то в этом роде? - person Steve; 27.05.2012
comment
После создания UserControl я устанавливаю DataContext, и FindVisualChild вызывается, когда возникает событие DataContextChanged. - person user1308583; 27.05.2012
comment
Только что попытался обновить сетку в событии Loaded, и это сработало! Спасибо за совет - person user1308583; 27.05.2012