列表框不会更新ItemsSource的内容

时间:2014-10-01 08:02:07

标签: wpf binding itemscontrol itemssource

我对ListBox有一个奇怪的问题: 我已将它绑定到未实现INotifyCollectionChanged的Collection(不可能,因为它的项目是根据请求动态生成的):

IEnumerator IEnumerable.GetEnumerator()
{
    foreach (var metaData in Metadata.Where((m) => m.IsEnabled))
    {
        yield return new DynamicPropertyValue(this, metaData);
    }
}

因此,当ListBox的IsVisible发生变化时,我试图通过将ItemsSource设置为Null来强制更新ItemsSource,然后更新绑定:

static void ItemsControl_IsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
{
    if (true.Equals(e.NewValue))
    {
        var element = (ItemsControl)sender;
        var bindingExpression = BindingOperations.GetBindingExpression(element, ItemsControl.ItemsSourceProperty);
        if (bindingExpression != null)
        {
            element.SetCurrentValue(ItemsControl.ItemsSourceProperty, null);
            bindingExpression.UpdateTarget();

            var count = element.ItemsSource.OfType<object>().Count();
            if (count != element.Items.Count)
            {
                Debug.WriteLine("Wrong number of items");
            }
        }
    }
}

当ItemsSource设置为Null时,ItemsControl不再包含任何项目,而Items集合是empt,正如预期的那样。但是,再次应用绑定时,将还原所有旧项目。 Items集合包含与以前相同的实例。调用GetEnumerator方法,但忽略新项目。

我不明白为什么会这样,或者我怎么能避免ItemsControl缓存其项目。

亚历

2 个答案:

答案 0 :(得分:2)

我偶然发现了你的帖子,试图弄清楚如何完成同样的事情。不想使用反射,我继续研究并找到了更好的答案。 :)

我仍在尝试习惯的一件事是,如何通过直接调用您感兴趣的对象的成员来访问WPF中的这么多功能,而是调用静态成员执行某些操作实现目标的幕后魔术。

如果我理解你的情况正确,你的情况就是其中之一。特别是,当你发现通过反射获得CollectionView对象完成了你的目标时,&#34;对&#34;这样做的方法是使用CollectionViewSource类来检索绑定对象的CollectionView

如果没有更完整的代码示例,我无法说出您的方案中的确切代码是什么样子。但基本的想法是做这样的事情:

CollectionViewSource.GetDefaultView(itemsSourceObject).Refresh();

即。这会查找绑定到ItemsSource属性的对象的默认视图(也就是说,它假定一个名为itemsSourceObject的变量并将其值传递给方法),然后当然调用{{1更新视图的方法。

答案 1 :(得分:0)

由于ListBox.Items.Refresh()没有达到预期效果,我尝试在底层CollectionView上刷新。并且voilà - ListBox更新。但问题是,访问此CollectionView的唯一方法是使用Reflection,因为属性是内部的:

var collectionViewProperty = typeof (ItemCollection).GetProperty("CollectionView", BindingFlags.Instance | BindingFlags.NonPublic);
var collectionView = (CollectionView) collectionViewProperty.GetValue(itemsControl.Items);
collectionView.Refresh();

似乎为与ItemsControl一起使用的每个ItemsSource缓存了CollectionView。有没有办法改变这种行为?

相关问题