简体   繁体   中英

Binding an ObservableCollection to an ItemsControl - not as simple as it sounds?

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;
        }
    }
}

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 :)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM