当引发propertychangedtrigger或datastorechangedtrigger时,ListBox ItemsSource和Items为空

时间:2011-11-16 18:32:34

标签: wpf mvvm

我有一个列表框,我正在尝试构建一个触发器。基本上我希望在更新ItemsSource或Items时触发我的触发。我尝试使用PropertyChangedTrigger和DataStoreChangedTrigger。问题是当这些触发器中的任何一个被执行时,我的ItemsSource在那时是空的。所以问题是我可以通过什么事件来了解我的ItemsSource何时被更改?我正在使用mvvm模式,因此不能有任何代码。这是一些代码

<ListBox x:Name="commentaryViewItems" 
        VirtualizingStackPanel.IsVirtualizing="False" 
        Background="White" 
        ItemsSource="{Binding CommentaryItemViewsModels}">
<iy:Interaction.Triggers>
    <is:DataStoreChangedTrigger Binding="{Binding Path=ItemsSource, ElementName=commentaryViewItems}">
        <localBehaviors:AutoScrollingTargetedTriggerAction></localBehaviors:AutoScrollingTargetedTriggerAction>
    </is:DataStoreChangedTrigger>                                        
</iy:Interaction.Triggers>
<ItemsControl.ItemTemplate>
    <DataTemplate>
        <local:CommentaryItemView DataContext="{Binding}"></local:CommentaryItemView>
    </DataTemplate>
</ItemsControl.ItemTemplate>
</ListBox>



public class AutoScrollingTargetedTriggerAction : TriggerAction<ListBox>
{
protected override void Invoke(object parameter)
{
    ListBox items = AssociatedObject as ListBox;

    if (items != null)
    {
        ItemCollection commentaryItemViewModels = items.Items;

        if (commentaryItemViewModels != null)
        {
            IList<ICommentaryItemViewModel> viewModels = new List<ICommentaryItemViewModel>();
            foreach (var viewModel in commentaryItemViewModels)
            {
                ICommentaryItemViewModel currentViewModel = viewModel as ICommentaryItemViewModel;
                if (currentViewModel != null)
                    viewModels.Add(currentViewModel);
            }

            if (viewModels.Count > 0)
            {
                // if there is more than one date header go to first one and move scroll to there
                if (viewModels.Count(c => c.IsTitleBarVisible == true) > 1)
                {
                    // get first viewmodel with header
                    ICommentaryItemViewModel viewModel =
                        viewModels.FirstOrDefault(f => f.IsTitleBarVisible == true);
                    if (viewModel != null)
                        items.ScrollIntoView(viewModel.View);
                }

                // if there is only one header move scroller to last item
                if (viewModels.Count(c => c.IsTitleBarVisible == true) == 1)
                {
                    ICommentaryItemViewModel viewModel =
                        viewModels.FirstOrDefault(f => f.IsTitleBarVisible == true);
                    if (viewModel != null)
                        items.ScrollIntoView(viewModel.View);
                }
            }
        }
    }
}
}

2 个答案:

答案 0 :(得分:0)

如果您使用ObservableCollection<T>作为ItemsSource,它将处理收集更改的事件。

答案 1 :(得分:0)

我正在使用一个可观察的集合。问题是我正在尝试根据其中包含的项目滚动我的列表框。因此,当observablecollection发生更改时,不一定是列表框已更新的时间。我最终做的是挂在我下面的一个点击按钮,这似乎是在适当的时候发生的。