我有一個封裝了一堆集合的類。我想將此類綁定到列表框以顯示集合中的項目。該類實現IEnumerable。當列表框顯示時,我期待IEnumerable.GetEnumerator方法被調用。然而,GetEnumerator方法不使用yield關鍵字。但是,如果我要從列表集合中返回枚舉器,它將正常工作,每次顯示窗口時都會調用GetEnumerator方法。無法使用收益綁定到IEnumerable實現
列表集合的枚舉器如此神奇? 什麼是實現允許WPF itemscontrol獲取快照的正確界面(不需要更新)??? IList是一個使用?
下面的示例代碼會在每次打開一個新窗口時添加一個時間戳。但是,列表框永遠不會顯示多個時間戳,即調用第一個(也是唯一一次)GetEnumerator的時間戳數。數量增加,所以添加時間戳。更改GetEnumerator方法以返回列表集合的枚舉器將導致每次打開新窗口時調用GetEnumerator方法。
XAML:
<Window x:Class="YieldTest.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<StackPanel>
<Button Content="Open" Click="Button_Click" />
<TextBlock Text="{Binding Path=Count}" />
<ListBox ItemsSource="{Binding}" />
</StackPanel>
</Window>
後面的代碼:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;
namespace YieldTest
{
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
Window1 window1 = new Window1();
window1.DataContext = _timeStamps;
_timeStamps.Add(DateTime.Now);
window1.Show();
}
private static TimeStamps _timeStamps = new TimeStamps();
}
public class TimeStamps : IEnumerable
{
public void Add(DateTime time1)
{
_timeStamps.Add(time1);
}
public int Count { get { return _timeStamps.Count; } }
public IEnumerator GetEnumerator()
{
Debug.WriteLine("GetEnumerator");
// Returning the enumerator of _timeStamps will result in
// GetEnumerator called every time a new window is opened,
// which is the expected result
// return _timeStamps.GetEnumerator();
// Using yield will result in GetEnumerator is called only
// one time for the first window opened. This means that
// newer windows will have stale data.
foreach (DateTime timeStamp in _timeStamps)
{
yield return timeStamp;
}
}
private List<DateTime> _timeStamps = new List<DateTime>();
}
}
我發現爲我獲得可綁定數據源的兩種解決方案是要麼實現IList和IEnumerator,要麼實現IEnumerable和INotifyCollectionChanged。我決定讓數據源實現IEnumerable和INotifyCollectionChanged,因爲它實現的不多,並且項目不能被客戶端代碼添加。 – 2010-08-23 14:12:49