Эффективный способ создания элементов представления wpf по запросу с помощью флага виртуальной машины

Обычно мои элементы представления создаются стандартным методом привязки ControlControl.Content к свойству, содержащему виртуальную машину или null. Это хорошо, потому что WPF создаст элемент представления (через неявный DataTemplate) только в том случае, если виртуальная машина действительно существует.

У меня есть еще один фрагмент пользовательского интерфейса, видимость которого переключается с помощью флага виртуальной машины. Обычно я бы использовал для этого boolToVisibilityConverter. Однако создание такой части пользовательского интерфейса достаточно дорого и редко появляется.

Вместо этого я хочу перейти к построению представления только в том случае, если флаг включен. Я придумал следующее:

<ContentControl>
    <ContentControl.Style>
        <Style TargetType="ContentControl">
            <Style.Triggers>
                <DataTrigger Binding="{Binding SomeVMFlag}" Value="True">
                    <Setter Property="Content">
                        <Setter.Value>
                            <vw:ExpensiveView/>
                        </Setter.Value>
                    </Setter>
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </ContentControl.Style>
</ContentControl>

Это кажется довольно неуклюжим, и я не могу избавиться от ощущения, что есть способ лучше? Какие-либо предложения?

Что мешает вам использовать тот же подход (раскрытие модели представления только при изменении SomeVMFlag) для этого представления?

dymanoid 31.10.2018 11:51

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

GazTheDestroyer 31.10.2018 11:58

Вы все еще можете раскрыть его с помощью свойства типа public SomeVM SomeVM { get { return SomeVMFlag ? this : null; }}. Конечно, с уведомлением об изменении свойства.

Clemens 31.10.2018 12:19

Правда! В какой-то момент я бы повторно объявил новый шаблон представления, что сделало бы его немного более беспорядочным, но мог бы попробовать его и посмотреть, как он себя чувствует. Спасибо обоим.

GazTheDestroyer 31.10.2018 12:22

В зависимости от используемой среды MVVM это может быть уже доступно. Различные модели представлений сопоставляются с разными представлениями, поэтому, когда вы привязываете ViewModel к ContentControl, соответствующее представление будет загружено на основе тип виртуальной машины.

Panagiotis Kanavos 31.10.2018 13:54

Вы можете использовать ContentTemplateSelector вашего ContentControl, чтобы выбрать шаблон на основе вашей собственной логики. Вы можете создать свой собственный DataTemplateSelector для реализации этой логики

Panagiotis Kanavos 31.10.2018 14:06
0
6
55
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Согласно предложению динамоида и Клеменса. Я реализовал отдельное фиктивное свойство виртуальной машины, которое просто возвращает родительскую виртуальную машину, когда установлен флаг.

Тогда просто посмотреть:

<ContentPresenter Content="{Binding DummyExpensiveVM}">
    <ContentPresenter.ContentTemplate>
        <DataTemplate>
            <vw:ExpensiveView />
        </DataTemplate>
    </ContentPresenter.ContentTemplate>
</ContentPresenter>

Намного чище, большое спасибо обоим.

РЕДАКТИРОВАТЬ: Нет! Это делает работу НЕТ, поскольку шаблон является литералом и создается независимо от содержимого. Я подозреваю, что то же самое можно сказать и о моей первоначальной реализации.

Вместо этого шаблон должен быть неявным шаблоном, определенным в ресурсах представления, как обычно для MVVM.

Другие вопросы по теме