ObservableCollection не обновляет источник элемента

У меня есть наблюдаемая коллекция, которая заполняется из сетевого потока. Если заполнить OC из конструктора фиктивными данными, он появится в интерфейсе пользователя. Я знаю, что элементы добавляются в коллекцию из сетевого потока, но количество элементов никогда не обновляется в пользовательском интерфейсе.

Моя модель зрения выглядит следующим образом:

public class ManikinStatusViewModel : DiViewModelBase
{
    private readonly ICommunicationService manikinCommunicationService;

    #region Properties
    public ObservableCollection<CasualtyStatusViewModel> Manikins { get; private set; }
    #endregion

    public ManikinStatusViewModel()
    {
        Manikins = new ObservableCollection<CasualtyStatusViewModel>();

        uow = UnitOfWorkFactory.Instance.CreateRunScenarioUnitOfWork(false);

        AccelermeterPacketData apd = new AccelermeterPacketData(56, 57, 58);

        manikinCommunicationService = new TestingCommunicationService(LoadAnalogSensorData(), apd);
        manikinCommunicationService.ManikinDataReceived += ManikinCommunicationService_ManikinDataReceived;

    }

    #region Events
    private void ManikinCommunicationService_ManikinDataReceived(object sender, ManikinDataReceivedEventArgs e)
    {
        if (e.ManiknDataPacket != null)
        {
            var manikin = Manikins.ToList().Find(m => m.ManikinId == e.ManiknDataPacket.SerialNumber);

            if (manikin == null)
            {
                Debug.WriteLine("Creating manikin with serial number: " + e.ManiknDataPacket.SerialNumber);

                CasualtyStatusViewModel csvm = new CasualtyStatusViewModel(e.ManiknDataPacket.SerialNumber);
                Manikins.Add(csvm);

                manikin = csvm;

                Debug.WriteLine("manikin count is: " + Manikins.Count());

            }

            manikin.UpdateManikinStatus(e.ManiknDataPacket);
        }
    }

    #endregion

Я связываю коллекцию манекенов со следующим взглядом.

   <TabControl Grid.Row="1" ItemsSource="{Binding Manikins}" Name="ManikinsTabControl">
        <TabControl.Resources>
            <Style TargetType="TabItem">
                <Setter Property="Header" Value="Casualty"></Setter>
                <Setter Property="ContentTemplate" Value="{StaticResource CasualtyTemplate}"></Setter>
            </Style>
        </TabControl.Resources>
    </TabControl>

6 ответов

Решение

Таким образом, существует два типа наблюдаемых коллекций, один в System.Collections.ObjectModel; один в Remotion.Linq.Collections; По-видимому, коллекция Remotion не обновляется должным образом при использовании отдельного потока. Изменено на System.Collections.ObjectModel и теперь все работает нормально.

Вы должны вызвать событие PropertyChanged при обновлении коллекции в своей модели представления, и ваша модель представления должна реализовывать INotifyPropertyChanged

Пользовательский интерфейс не знает, когда ваша коллекция обновляется. Вы должны на самом деле уведомить об этом. Чтобы сделать это, выполните следующие действия:

  1. Внедрить / наследовать от INotifyPropertyChanged

  2. Скопируйте и вставьте этот код. Я не буду вдаваться в подробности, но это довольно общий код, который можно использовать с любым классом.

    public event PropertyChangedEventHandler PropertyChanged;
    
    protected virtual void OnPropertyChanged(string PropertyName)
    {
        PropertyChangedEventHandler handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(PropertyName));
        }
    }
    
  3. Теперь, когда ваш список обновляется, звоните OnPropertyChanged метод и передать имя свойства, которое изменилось. (В твоем случае OnPropertyChanged("Manikins"))

ObservableCollection обновляет пользовательский интерфейс, когда событие CollectionChanged фактически возникает, когда вы добавляете / удаляете элемент в этой коллекции... если удерживаемая коллекция изменила пользовательский интерфейс, обновляться не будет... я видел, что вы использовали метод Manikins.Add() и на самом деле это странно, что пользовательский интерфейс не обновляется, поэтому сначала проверьте, действительно ли в коллекцию добавлен элемент, во-вторых, убедитесь, что в вашем коде нет ничего, что настраивает всю коллекцию на новую ссылку... Надеюсь, это помогло

Вам нужно добавить элементы в ObservableCollection<> в потоке пользовательского интерфейса, чтобы перекрасить / обновить элементы управления по мере необходимости.

Вы пытались использовать поток Distacher для синхронного добавления элементов в поток пользовательского интерфейса? Вот что можно попробовать:

Вместо:

Manikins.Add(csvm);

Вы заменяете на:

Dispatcher.BeginInvoke(DispatcherPriority.Normal , new Action(() => 
{ 
    Manikins.Add(csvm); 
} 
));

Надеюсь это hepls

Другие вопросы по тегам