Привязка ObservableCollection к ItemsControl - не так просто, как кажется? - PullRequest
2 голосов
/ 18 ноября 2011

Это было очень трудно отследить и причинило мне большую боль - но кажется 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;
        }
    }
}

1 Ответ

5 голосов
/ 18 ноября 2011

Ахмм. После того, как я попробовал его в моем устройстве, которое использует .NET 4.0, и это сработало, я думаю, что это проблема в .NET 3.5.Если ваши клиенты настаивают на том, чтобы использовать его в версии .NET 3.5, порекомендуйте им перейти на .NET 4.0, и эта проблема должна быть закрыта.спасибо:)

...