2014-10-01 96 views
0

的內容我有一個奇怪的問題,一個ListBox: 我把它綁定到不實現INotifyCollectionChanged(不可能的,因爲它的項目要求動態生成)的集合:列表框不更新的ItemsSource

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

因此,當ISVISIBLE的ListBox的變化,我試圖武力將其設置爲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集合已被清空。但是,再次應用綁定時,所有舊項目都會恢復。 Items集合包含與之前相同的實例。 GetEnumerator方法被調用,但新項目被忽略。

我不明白爲什麼這是這種情況,或者我可以如何避免ItemsControl緩存它的項目。

亞歷

+1

爲什麼不只是創建一個新的集合並將其分配給ItemSource屬性? – Clemens 2014-10-01 08:18:27

+0

'element.SetCurrentValue(ItemsControl.ItemsSourceProperty,null);'我相信這隻會將您的'ItemsControl.ItemSource'設置爲'null',您的代碼在哪裏更新集合? – Bolu 2014-10-01 08:30:06

+0

集合可以在多個(未連接的)對象上共享。當我在一個位置替換它時,我將不得不在任何地方替換它。但我無法訪問所有這些地方。 – LionAM 2014-10-01 08:33:51

回答

1

我偶然發現你的文章試圖找出如何完成同樣的事情。不想使用反思,我一直在研究並找到更好的答案。 :)

我仍然試圖去習慣的一件事情是WPF中的如此多功能是如何訪問的,而不是通過直接調用您感興趣的對象的成員,而是調用靜態成員一些幕後的魔法來實現這一目標。

如果我正確理解您的方案,那麼您就是其中一種情況。特別是,雖然您發現通過反射獲取對象實現了目標,但「正確」的方法是使用CollectionViewSource類爲綁定對象檢索CollectionView

沒有一個更完整的代碼示例,我不能說你的方案中的確切代碼是什麼樣子。但基本的想法是做這樣的事情:

CollectionViewSource.GetDefaultView(itemsSourceObject).Refresh(); 

即,這將查找綁定到ItemsSource屬性的對象的默認視圖(即,它假定一個名爲itemsSourceObject的變量並將其值傳遞給方法),然後調用Refresh()方法更新視圖。

+0

謝謝。有用。你是怎樣找到它的?你知道如果有多個ListBox實例(具有相同的ItemsSource)會發生什麼?都更新 - 或只有其中一個...... – LionAM 2015-03-03 14:03:46

+0

@LionAM:我真的不記得我是如何找到它的。我確定我正在尋找「CollectionView」和其他一些關鍵詞,但我不記得具體細節。如果集合綁定到多個'ItemsControl'('ListBox'或其他),則全部都應該更新。 – 2015-03-04 01:00:04

+0

@LionAM:請注意,這僅適用於您直接綁定集合(導致WPF使用默認視圖)的情況;如果你明確地創建了你自己的視圖,那麼顯然這個視圖被用來代替默認視圖,而你需要刷新那個視圖。當然,在這種情況下,由於自己創建了視圖,因此更容易找到(即自己存儲引用):) – 2015-03-04 01:00:41

0

作爲ListBox.Items.Refresh()不具有所期望的效果,我試圖在下層的CollectionView刷新。而且 - 列表框更新。與此問題,但是,是唯一的方法訪問此的CollectionView,採用反射,作爲物業是內部:

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

看來,的CollectionView緩存爲與ItemsControl的使用的每個的ItemsSource。有什麼方法可以改變這種行爲嗎?