Prerendering/hiding при загрузке с WPF MVVM?
У меня есть элемент управления, закодированный в WPF, который может содержать один из трех дочерних элементов - два SimpleChildElements и один ComplexChildElement, скажем - и свопы между отображением их в зависимости от некоторой закулисной логики в модели, которая позволяет я делаю это.
<ItemsControl
ItemsSource="{Binding ChildPanels.Values}"
Name="ContentControl1"
>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"
Visibility="{Binding Path=Active, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Детские элементы - это собственные ViewModels, и у меня есть некоторые ресурсы, объявленные выше по течению, поэтому для них есть DataTemplates. Я могу разработать больше, если это поможет, но захватывающий элемент проблемы таков:
Когда я прокручиваю элементы в главном элементе управления, а ComplexChildElement появляется впервые, появляется короткое, едва заметное мерцание, когда оно украшается - это куча со списков, украшенных DevExpress. Эта настройка означает, что нет мерцания при прокрутке записи с помощью ComplexChildElement и обратно, и если я начну показывать главный элемент управления с помощью ComplexChildElement, там нет мерцания, когда он снова появится.
Но главный элемент управления подключен к другому источнику данных, и я не могу гарантировать, что в первой записи будет элемент ComplexChildElement, который загружается при инициализации с помощью большей структуры отображения, которую я действительно не хочу корневать в на данный момент.
Итак, как я могу гарантировать, что ComplexChildElement будет отображаться при загрузке формы и, возможно, скрыть ее сразу после? Я уже пробовал включить ChildPanels.Active внутри функции за этим:
<dxmvvm:Interaction.Triggers>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding OnViewLoadedCommand}" />
</dxmvvm:Interaction.Triggers>
но это не делает их рендерингом.
Эта функция, кстати:
foreach (var childModel in ChildPanels.Values)
{
childModel.Active = true;
RaisePropertyChanged(() => childModel.Active);
}
ChangeChildModel();
с последним вызовом функции, вызываемым для изменения видимости дочерней модели при изменении записи. Если я не сделаю этот последний вызов, все модели просмотра для детей начнут видны.
Ответы
Ответ 1
Почему бы не установить с видимость значение false с самого начала? Это не помешает вам впоследствии использовать привязку Активно.
Связывание в порядке, но поскольку оно используется DataTemplate для изменения видимости и родительским элементом управления, чтобы узнать, должен ли он отображать дочерний элемент управления. Поэтому в зависимости от порядка подписки на событие PropertyChanged родительский элемент управления может видеть или не видеть элемент управления как видимый.
Кстати, мне интересно, была ли ваша первая цель не предотвращать мерцание, которое может возникнуть при вызове Show/Hide на нескольких элементах управления. Я не уверен, что предварительный рендеринг является правильным решением для этого.
В зависимости от основной причины мерцания на SO есть уже несколько исправлений: