我有以下ListBox,ContentControl为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>
每个有界实例都有&#39; IsSelected&#39;通过INotifyPropertyChanged
:
public bool IsSelected
{
get { return isSelected; }
set
{
isSelected = value;
notify("IsSelected");
}
}
我构建了一个自定义行为,用于查看将其更改为IsSelectedProperty的元素,如下所示:
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);
}
}
此时此项未显示在UI上,因为它位于列表底部(有一个滚动条)。
我使用IsSelected
值更新了true
属性。
但是,我们应该更新它的有界属性时执行customIsSelectedPropertyChanged_Callback
方法。
但是,实际上,只有在将滚动条向下移动到UI上时,才会调用此项目。
答案 0 :(得分:5)
最有可能的原因是UI虚拟化。 ListBox
项主机默认为VirtualizingStackPanel
。它不会生成现在不可见的项目,因此当您在模型上设置IsSelected时,您的DataTemplate
以及您的行为尚未创建。只有向下滚动时,控件才会与数据模板中的行为一起创建,绑定后CustomIsSelectedProperty
设置为true,因此调用回调。
要验证此假设,您可以停用ListBox
的UI虚拟化,看看是否能解决问题。