gpt4 book ai didi

c# - ICollectionView 的 SourceCollection 为空

转载 作者:太空狗 更新时间:2023-10-29 20:52:47 26 4
gpt4 key购买 nike

我有一个包含两个 ICollectionView 的 ViewModel s 绑定(bind)为 ItemsSource s 到两个不同的 ListBox es。两者包装相同 ObservableCollection ,但具有不同的过滤器。最初一切正常,两个列表框都显示正确填充。

但是,当我更改 ObservableCollection 中的项目并修改与过滤相关的属性时,ListBoxes 不会更新。在调试器中,我发现两个 ICollectionVIews 的 SourceCollection 都是空的,尽管我的 ObservableCollection 仍然存在。

这是我修改项目的方式,通过删除和添加相同的项目确保更新 ICollectionViews:

private void UnassignTag(TagViewModel tag)
{
TrackChangedTagOnCollectionViews(tag, t => t.IsAssigned = false);
}

private void TrackChangedTagOnCollectionViews(TagViewModel tag, Action<TagViewModel> changeTagAction)
{
_tags.Remove(tag);

changeTagAction.Invoke(tag);

_tags.Add(tag);
}

该机制在我使用相同类的另一个上下文中工作。

我还意识到,如果我在 ICollectionViews 的 CollectionChanged 事件上注册监听器,问题就会消失。我确保我从 GUI 线程创建和修改它们并怀疑垃圾收集是问题所在,但目前我被卡住了......想法?

更新:

调试时我意识到 SourceCollections 在我调用 ShowDialog() 之前仍然存在在承载我的 UserControl 的 WinForms 窗体上。当显示对话框时,它们就消失了。

我这样创建 ICollectionViews:

AvailableTags = new CollectionViewSource { Source = _tags }.View;
AssignedTags = new CollectionViewSource { Source = _tags }.View;

这是我绑定(bind)两者之一的方法(另一个非常相似):

<ListBox Grid.Column="0"  ItemsSource="{Binding AvailableTags}" Style="{StaticResource ListBoxStyle}">
<ListBox.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource ListBoxItemBorderStyle}">
<DockPanel>
<Button DockPanel.Dock="Right" ToolTip="Assign" Style="{StaticResource IconButtonStyle}"
Command="{Binding Path=DataContext.AssignSelectedTagCommand, RelativeSource={RelativeSource AncestorType={x:Type tags:TagsListView}}}"
CommandParameter="{Binding}">
<Image Source="..."/>
</Button>

<TextBlock Text="{Binding Name}" Style="{StaticResource TagNameTextBlockStyle}"/>
</DockPanel>
</Border>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>

我使用 MvvmLight 的 RelayCommand<T>作为ICommand在我的 ViewModel 中实现:

AssignSelectedTagCommand = new RelayCommand<TagViewModel>(AssignTag);

最佳答案

我也有这个问题,有类似的用例。当我更新基础集合时,我会在所有过滤的 View 上调用 Refresh()。有时,这会导致从 ListCollectionView.PrepareLocalArray() 中抛出 NullReferenceException,因为 SourceCollection 为 null。

问题是您不应绑定(bind)到 CollectionView,而应绑定(bind)到 CollectionViewSource.View 属性。

这是我的做法:

public class ViewModel {

// ...

public ViewModel(ObservableCollection<ItemViewModel> items)
{
_source = new CollectionViewSource()
{
Source = items,
IsLiveFilteringRequested = true,
LiveFilteringProperties = { "FilterProperty" }
};

_source.Filter += (src, args) =>
{
args.Accepted = ((ItemViewModel) args.Item).FilterProperty == FilterField;
};
}

// ...

public ICollectionView View
{
get { return _source.View; }
}

// ...
}

关于c# - ICollectionView 的 SourceCollection 为空,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28435477/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com