Mvvm 虚拟化stackpanel-虚拟化项目可见性

Mvvm 虚拟化stackpanel-虚拟化项目可见性,mvvm,visibility,virtualization,itemcontainerstyle,itemcontainergenerator,Mvvm,Visibility,Virtualization,Itemcontainerstyle,Itemcontainergenerator,我有一个场景,在这个场景中,我使用一个列表框来显示一个大的ViewModels列表,每个ViewModels都有一个可视性属性,该属性根据应用程序逻辑而变化 我遇到的问题是,当“虚拟化”项目的可见性发生变化时,滚动条不会更新以反映可滚动范围,直到通过手动滚动将项目带入视图 这显然是由于虚拟化项目没有评估可见性绑定,因此没有添加到可滚动范围中,但如何在不禁用可视化的情况下解决此问题 注意:我知道我可以使用filtering CollectionView,但是Visibility属性更适合我的应用程

我有一个场景,在这个场景中,我使用一个列表框来显示一个大的ViewModels列表,每个ViewModels都有一个可视性属性,该属性根据应用程序逻辑而变化

我遇到的问题是,当“虚拟化”项目的可见性发生变化时,滚动条不会更新以反映可滚动范围,直到通过手动滚动将项目带入视图

这显然是由于虚拟化项目没有评估可见性绑定,因此没有添加到可滚动范围中,但如何在不禁用可视化的情况下解决此问题

注意:我知道我可以使用filtering CollectionView,但是Visibility属性更适合我的应用程序逻辑

下面是一些演示该问题的代码

    public class ViewModel : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;
    public string Name { get; private set; }
    public Visibility Visibility
    {
        get { return m_visibility; }
        set
        {
            m_visibility = value;
            RaisePropertyChanged("Visibility");
        }
    }

    public ViewModel(string name)
    {
        Name = name;
    }

    protected void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    Visibility m_visibility = Visibility.Visible;
}

public partial class MainWindow : Window
{
    public List<ViewModel> ViewModels { get; private set; }

    public MainWindow()
    {
        ViewModels = new List<ViewModel>();

        for(int i = 0; i < 100; ++i)
        {
            ViewModels.Add(new ViewModel("item_" + i));
        }

        DataContext = this;
        InitializeComponent();
    }

    void OnHideItemsClick(object sender, EventArgs e)
    {
        for (int i = 30; i < ViewModels.Count; ++i)
        {
            ViewModels[i].Visibility = Visibility.Collapsed;
        }
    }

    void OnShowItemsClick(object sender, EventArgs e)
    {
        for (int i = 30; i < ViewModels.Count; ++i)
        {
            ViewModels[i].Visibility = Visibility.Visible;
        }
    }
}


<DockPanel>
    <UniformGrid Columns="2" DockPanel.Dock="Top">
        <Button Content="Hide offscreen items" Click="OnHideItemsClick" />
        <Button Content="Show offscreen items" Click="OnShowItemsClick" />
    </UniformGrid>
    <ListBox ItemsSource="{Binding ViewModels}" HorizontalContentAlignment="Stretch">
        <ListBox.ItemContainerStyle>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Visibility" Value="{Binding Visibility}" />
            </Style>
        </ListBox.ItemContainerStyle>
        <ListBox.ItemTemplate>
            <DataTemplate>
                <Border Margin="1" BorderThickness="1" BorderBrush="Green">
                    <TextBlock Text="{Binding Name}" Margin="5" />
                </Border>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
</DockPanel>
公共类视图模型:INotifyPropertyChanged
{
公共事件属性更改事件处理程序属性更改;
公共字符串名称{get;private set;}
公众能见度
{
获取{return m_visibility;}
设置
{
m_可见性=值;
提升属性更改(“可见性”);
}
}
公共视图模型(字符串名称)
{
名称=名称;
}
受保护的void RaisePropertyChanged(字符串属性)
{
if(PropertyChanged!=null)
{
PropertyChanged(此,新PropertyChangedEventArgs(property));
}
}
可见性m_Visibility=可见性。可见;
}
公共部分类主窗口:窗口
{
公共列表视图模型{get;private set;}
公共主窗口()
{
ViewModels=新列表();
对于(int i=0;i<100;++i)
{
添加(新的ViewModel(“项_”+i));
}
DataContext=this;
初始化组件();
}
void OnHideItemsClick(对象发送方,事件参数e)
{
对于(int i=30;i