Reputation: 1738
This has been very difficult to track down and has caused me a great deal of pain - but it seems ItemsControls
do not behave the way I would expect. It almost seems like a bug in WPF - but being new to WPF I'm erring on the side of it's my fault, not theirs.
To reproduce it is very simple - bind an ItemsControl
to an ObservableCollection
, and then replace an item in the collection. It's so simple I cannot believe Google doesn't find thousands of people with the same problem.
The code below simply binds an ItemsControl
to an ObservableCollection
of Brush
. Change a brush (by clicking the button), and you get a couple of data errors as the rectangle's brush binding is momentarily of the DataContext
of the ItemsControl
(!), rather than of the new item. This momentary crash of bindings has caused my application to take over half a second to update when run in the debugger whenever I replace an (immutable, regular CLR object) item in the collection - what am I doing wrong?
<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;
}
}
}
Upvotes: 2
Views: 4574
Reputation: 10175
Ahmm After trying it in my unit which uses .NET 4.0 and it worked out I think this is a problem in .NET 3.5. If you're clients are insisting to use it in .NET 3.5 Version advice them to upgrade to .NET 4.0 and this problem shall be closed. thanks :)
Upvotes: 5