I have the following ListBox with the ContentControl as DataTemplate:
<ListBox x:Name="lstActionConfigs" ItemsSource="{Binding Path=AllActionConfigList}" SelectedItem="{Binding Path=ListSelectedItem, Mode=TwoWay}" HorizontalContentAlignment="Stretch" Grid.Row="3" Margin="0,0,0,5">
<ListBox.ItemTemplate>
<DataTemplate DataType="{x:Type helper:ItemDetails}">
<ContentControl Template="{StaticResource ResourceKey=actionDetailsListItemTemplate}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<i:Interaction.Behaviors>
<behaviours:BringIntoViewBehaviour CustomIsSelected="{Binding Path=IsSelected, Mode=TwoWay}"/>
</i:Interaction.Behaviors>
</ContentControl>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Each bounded instance has 'IsSelected' property which notify the UI on changes via INotifyPropertyChanged:
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
notify("IsSelected");
}
}
I built a custom behavior that brings into view the elements that changed it's IsSelectedProperty to true, as the follows:
public class BringIntoViewBehaviour : Behavior<FrameworkElement>
{
public bool CustomIsSelected
{
get { return (bool)GetValue(CustomIsSelectedProperty); }
set { SetValue(CustomIsSelectedProperty, value); }
}
public static readonly DependencyProperty CustomIsSelectedProperty =
DependencyProperty.Register("CustomIsSelected", typeof(bool), typeof(BringIntoViewBehaviour), new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, new PropertyChangedCallback(customIsSelectedPropertyChanged_Callback)));
private static void customIsSelectedPropertyChanged_Callback(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
BringIntoViewBehaviour thisControl = o as BringIntoViewBehaviour;
if (thisControl == null)
return;
bringIntoView(thisControl);
}
}
This item is not presented this moment on the UI as it located at the bottom of the list (there is a scroll bar).
I updated the IsSelected property with true value.
However, the customIsSelectedPropertyChanged_Callback method should be executed as we updated it's bounded property.
But, in practice, this method is invoked only when this item is presented on UI when moving the scroll bar down to it.
The reason most likely is UI virtualization. ListBox items host is by default VirtualizingStackPanel. It will not generate items which are out of view now, so when you set IsSelected on your model, your DataTemplate together with your behaviour are not created yet. Only when you scroll down, control is created together with behaviour from data template, and after it is bound CustomIsSelectedProperty is set to true, so your callback is called.
To verify this assumption you can disable UI virtualization for your ListBox and see if that resolves the problem.
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