I've got a control coded in WPF that can have one of three child elements - two SimpleChildElements and one ComplexChildElement, let's say - and swaps between display of them depending on some behind-the-scenes logic in the model that lets me do this.
<ItemsControl
ItemsSource="{Binding ChildPanels.Values}"
Name="ContentControl1"
>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{Binding}"
Visibility="{Binding Path=Active, Converter={StaticResource BooleanToVisibilityConverter}}"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The child elements are their own ViewModels and I've got some resources declared upstream so there are DataTemplates for them. I can elaborate more if it'll help, but the gripping element of the problem is this:
When I'm scrolling through elements in the master control and ComplexChildElement pops up for the first time, there's a brief, barely visible flicker as it gets decorated -- it's a bunch of combo boxes decorated with DevExpress. This setup means there's no flicker when I scroll off a record with a ComplexChildElement and back again, and if I start display of the master control with a ComplexChildElement there, there's no flicker when it pops up again.
But the master control is keyed to another data source, and I can't guarantee there will be a ComplexChildElement in the first record, which is loaded on initialize by a larger display framework I really don't want to root around in at the moment.
So how can I guarantee ComplexChildElement will get rendered when the form loads, and possibly hide it immediately after? I've already tried toggling ChildPanels.Active on and off inside the function behind this:
<dxmvvm:Interaction.Triggers>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding OnViewLoadedCommand}" />
</dxmvvm:Interaction.Triggers>
but that doesn't get them to render.
That function, by the way:
foreach (var childModel in ChildPanels.Values)
{
childModel.Active = true;
RaisePropertyChanged(() => childModel.Active);
}
ChangeChildModel();
with the last function call being the one called to change the child model visibility when the record changes. If I don't do that last call, all the child view models start out visible.
Why not setting the Visibility to false right from the start? This doesn't prevent you from using the binding on Active afterwards.
Binding is OK, but as it is used by the DataTemplate to modify Visibility and by the parent control to know whether it should render the child control. So depending on the subscription order to the PropertyChanged event, the parent control may or may not see the control as Visible.
By the way, I'm wondering if your first goal was not to prevent flickering that may occurs when calling Show/Hide on several controls. I'm not sure pre rendering is the right fix for that.
Depending on the root cause of flickering, there are already several fixes on SO:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With