WPF - Treeview и ContentControl виртуализация - PullRequest
0 голосов
/ 21 марта 2019

У меня есть древовидная структура с источником данных, содержащим элементы пользовательского класса TreeviewItem.

У меня есть свойство SelectedTreeviewItemViewModel типа TreeviewItem.

public TreeviewItem SelectedTreeviewItemViewModel //with INPC

У меня есть элемент управления содержимым где-то еще в окне

        <ContentControl Content="{Binding SelectedTreeviewItemViewModel}" /> 

с табличкой данных следующим образом:

    <DataTemplate DataType="{x:Type TreeviewItem}">
        <uc:TreeviewCustomView />
    </DataTemplate>

Когда я щелкаю по элементу древовидной структуры, запускается событие SelectedItemChanged, и я устанавливаю SelectedTreeviewItemViewModel, который заставляет Contentcontrol обновлять свойcontent.

Логика в порядке, однако я заметил, что когда я нажимаю на новый элемент в древовидной структуре, некоторые данные обновляются, но я не захожу в конструктор пользовательского элемента управления (uc: TreeviewCustomView).

Существует ли какая-либо виртуализация?Я предполагаю, что WPF кеширует таблицу данных;Есть ли способ заставить WPF заново создавать пользовательский элемент управления с нуля (таким образом, входя в конструктор) каждый раз, когда я нажимаю на элемент дерева?

Ответы [ 2 ]

1 голос
/ 21 марта 2019

Вот что помогло мне:

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

В моем xaml я начинаю с именования шаблона данных:

    <DataTemplate x:Key="TreeviewItemTemplate" DataType="{x:Type TreeviewItem}">
        <uc:TreeviewCustomView />
    </DataTemplate>

Затем я создаю селектор шаблона следующим образом:

public class TreeviewItemTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item == null)
        {
            return null;
        }
        var declaredDataTemplate = ((FrameworkElement)container).FindResource("TreeviewItemTemplate") as DataTemplate;
        var wrappedDataTemplate = WrapDataTemplate(declaredDataTemplate );
        return wrappedDataTemplate;
    }

    private static DataTemplate WrapDataTemplate(DataTemplate declaredDataTemplate)
    {
        var frameworkElementFactory = new FrameworkElementFactory(typeof(ContentPresenter));
        frameworkElementFactory.SetValue(ContentPresenter.ContentTemplateProperty, declaredDataTemplate);
        var dataTemplate = new DataTemplate();
        dataTemplate.VisualTree = frameworkElementFactory;
        return dataTemplate;
    }
}

И, наконец, я использую селектор в моем управлении контентом:

<ContentControl Content="{Binding SelectedTreeviewItemViewModel }"
                ContentTemplateSelector="{StaticResource TreeviewItemTemplateSelector }" />
1 голос
/ 21 марта 2019

TreeViews виртуализируются по умолчанию при использовании привязки. Если вы переключите режим на VirtualizingPanel.VirtualizationMode = "Standard" вместо "Recycling", конструктор должен быть вызван.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...