我有以下XAML:爲什麼ListBox綁定到IEnumerable更新?
<Window x:Class="ListBoxTest.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ListBoxTest"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<local:Model />
</Window.DataContext>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ListBox ItemsSource="{Binding Items}" Grid.Row="0"/>
<Button Content="Add" Click="Button_Click" Grid.Row="1" Margin="5"/>
</Grid>
</Window>
,爲Model
類,它被放入主窗口的DataContext
以下代碼:
public class Model : INotifyPropertyChanged
{
public Model()
{
items = new Dictionary<int, string>();
}
public void AddItem()
{
items.Add(items.Count, items.Count.ToString());
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs("Items"));
}
private Dictionary<int, string> items;
public IEnumerable<string> Items { get { return items.Values; } }
public event PropertyChangedEventHandler PropertyChanged;
}
和主窗口中的代碼:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var model = this.DataContext as Model;
model.AddItem();
}
}
按下按鈕時,列表中的內容爲否正在更新。
然而,當我改變Items
屬性的getter這樣:
public IEnumerable<string> Items { get { return items.Values.ToList(); } }
它開始工作。
然後,當我註釋掉髮送了PropertyChanged
事件的部分時,它會停止再次工作,這表明事件正在正確發送。
因此,如果列表收到事件,爲什麼不能在第一個版本中正確更新它的內容,而不需要撥打ToList
?
你有沒有考慮過使用ObservableCollection? – heltonbiker
@heltonbiker它有嚴重的缺點 - 像缺少「AddRange」,也沒有其他可能性執行批量更新,這不會導致每個添加項目的更新。另外,我有一本字典不是一個普通的列表。 – BartoszKP
@BartoszKP有可用的可觀察字典的實現(只需搜索ObservableDictionary)。您可以將ListBox的ItemsSource直接綁定到ObservableDictionary,並將ListBox項目(在ItemTemplate中)綁定到字典條目的'Value'屬性。 – Clemens