Это было очень трудно отследить и причинило мне большую боль - но кажется ItemsControls
не ведет себя так, как я ожидал.Это почти похоже на ошибку в WPF - но, будучи новичком в WPF, я ошибаюсь, потому что это моя вина, а не их.
Воспроизвести это очень просто - привязать ItemsControl
к ObservableCollection
, а затем замените предмет в коллекции.Это так просто, я не могу поверить, что Google не находит тысячи людей с такой же проблемой.
Код ниже просто связывает ItemsControl
с ObservableCollection
из Brush
.Измените кисть (нажав на кнопку), и вы получите пару ошибок данных, поскольку привязка кисти прямоугольника на мгновение относится к DataContext
ItemsControl
(!), А не к новому элементу.Этот кратковременный сбой привязок заставил мое приложение обновляться за полсекунды при запуске в отладчике всякий раз, когда я заменяю (неизменяемый, обычный объект CLR) в коллекции - что я делаю неправильно?
<Window x:Class="Dummy.Test"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Test" Height="300" Width="300">
<Grid>
<ItemsControl ItemsSource="{Binding Foos}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="{x:Type Brush}">
<Rectangle Width="20" Height="20" Fill="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Button HorizontalAlignment="Center" VerticalAlignment="Bottom" Click="SwitchClick">Switch</Button>
</Grid>
</Window>
using System;
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Media;
namespace Dummy
{
public partial class Test : Window
{
private readonly ObservableCollection<Brush> foos = new ObservableCollection<Brush>();
public ObservableCollection<Brush> Foos { get { return foos; } }
public Test()
{
InitializeComponent();
Foos.Add(Brushes.Green);
DataContext = this;
}
private void SwitchClick(object sender, EventArgs e)
{
Foos[0] = Foos[0] == Brushes.Green ? Brushes.Silver : Brushes.Green;
}
}
}