Лучший способ принудительно обновить список WPF, привязанный к данным?

StackOverflow https://stackoverflow.com/questions/253036

Вопрос

У меня есть WPF ListBox, который привязан к ObservableCollection, когда коллекция изменяется, все элементы обновляют свое положение.

Новая позиция сохраняется в коллекции, но пользовательский интерфейс не обновляется.Поэтому я добавил следующее:

    void scenarioItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
    {
        ToolboxListItem.UpdatePositions();
        lstScenario.ItemsSource = null;
        lstScenario.ItemsSource = ToolboxListItem.ScenarioItems;
        this.lstScenario.SelectedIndex = e.NewStartingIndex;
    }

Установив для ItemsSource значение null и затем снова привязав его, пользовательский интерфейс обновляется,

но это, вероятно, очень плохое кодирование: p

Предложения?

Это было полезно?

Решение

У меня есть Listbox, привязанный к свойству object, которое имеет тип List<MyCustomType>() и я проверил, что следующий код обновляет listbox при обновлении списка.

void On_MyObjProperty_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
   MyListBox.Items.Refresh();
}

Если вы все еще сталкиваетесь с проблемами, просмотрите окно вывода VS IDE (Ctrl + W, O) и посмотрите, сможете ли вы обнаружить какие-либо сообщения об ошибках привязки.

Другие советы

WPF привязывает список / коллекцию элементов к ListBox, но пользовательский интерфейс не обновляется после обновления элементов, Решаемая.

Я просто глупая.В то время как я много читал об использовании ObservableCollection<> вместо того , чтобы List<>, Я просто продолжал игнорировать это предложение и следовал другим предложениям, но безрезультатно.Вернулся к своим книгам и перечитал.Это довольно хорошо объяснено, что ObservableCollection<> является обязательным использованием, потому что List<> не обеспечивает INotifyCollectionChange интерфейс, необходимый для ListBox чтобы обновить его отображение при изменении элементов в коллекции.

Это обновленный код:

private ObservableCollection<StringWrapper> m_AppLog;
ObservableCollection<StringWrapper> Log { get { return m_AppLog; } }

Довольно простой и не требует ничего другого (напримерОбновить()).Поскольку ObservableCollection сам заботится о запуске события изменения, я смог удалить ненужный вызов:

// notify bound objects
OnPropertyChanged("Log");

ObservableCollection не поддерживает обновление потоком, который его не создавал.Поскольку мой список (визуальный журнал для отображения последних ошибок / информационных сообщений) может обновляться из разных потоков, я добавляю, чтобы настроить свой код таким образом, чтобы убедиться, что обновление было выполнено с помощью собственного диспетчера списка:

public void AddToLog(string message) {
    if (Thread.CurrentThread != Dispatcher.Thread) {
        // Need for invoke if called from a different thread
        Dispatcher.Invoke(
            DispatcherPriority.Normal, (ThreadStart)delegate() { AddToLog(message); });
    }
    else {
        // add this line at the top of the log
        m_AppLog.Insert(0, new StringWrapper(message));
        // ...

Также обратите внимание , что ObservableCollection<> не поддерживает RemoveRange() вопреки List<>.Это часть возможных настроек, необходимых при переключении со списка на ObservableCollection.

Возможно, у меня проблема, похожая на ту, что у вас, но я не уверен.

У меня был ObservableCollection<MyEntity> и a ListBox привязанный к нему.Но для некоторых странная причина мой ListBox не обновлялся, когда я изменил свойства MyEntity объекты в списке.

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

http://www.wblum.org/listbind/net3/index.html

Это очень хорошее описание того, что вам нужно сделать, чтобы получить ListBox для обновления при изменении списка или объектов в нем.Надеюсь, вы извлечете из этого пользу.

Вчера у меня была такая же проблема, и это полный кусок дерьма :) ...Однако я больше не устанавливаю для своего значение null.В моем сценарии я устанавливаю для него значение myList.toArray() (после каждого добавления в список).

Я видел несколько "о, вам нужно использовать ObservableList". <-- полное дерьмо.

Я видел несколько "о, вызовите "Обновить"". <-- полное дерьмо.

Пожалуйста, простите мою огорченность, но я также ожидал бы, что это сработает :)

Это старый материал, но используйте ObservableCollection.ЕСЛИ вы хотите, чтобы пользовательский интерфейс видел обновления свойств в объектах ObservableCollection, вам необходимо реализовать INotifyPropertyChanged в определении класса для этого объекта.Затем вызовите событие изменения свойства в установщике каждого свойства.

Public Class Session
Implements INotifyPropertyChanged

Public Event PropertyChanged As PropertyChangedEventHandler _
   Implements INotifyPropertyChanged.PropertyChanged

Private Sub NotifyPropertyChanged(ByVal info As String)
    RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(info))
End Sub

Private _name As String = "No name"
''' <summary>
''' Name of Session
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Name() As String
    Get
        Return _name
    End Get
    Set(ByVal value As String)
        _name = value
        NotifyPropertyChanged("Name")
    End Set
End Property

Если у вас есть ObservableList объектов, и вы изменяете свойства внутри этих объектов, уведомление не применяется, поскольку коллекция не изменяется напрямую.Я вызывал уведомление после изменения свойств моего объекта с помощью Insert (), чтобы повторно добавить мой измененный объект в коллекцию, затем RemoveAt (), чтобы удалить старую копию.Это некрасиво, но это работает.

На мой взгляд, это больше похоже на ошибку в ListBox и ListView.Я привязываюсь к ObservableCollection, элементы в коллекции реализуют INotifyPropertyChanged .Пользовательский интерфейс не показывает добавленных элементов, когда я динамически нажимаю кнопку "добавить элемент", однако у меня есть элемент управления счетчиком, который привязан к MyCollection.Count.Этот элемент управления счетчиком увеличивается каждый раз, когда я нажимаю кнопку "Добавить элемент".Если я изменю размер представления, в окне списка отобразятся все мои добавленные элементы.Таким образом, привязка ItemSource к элементу управления ListBox нарушена.Я также позаботился о том, чтобы ни в коем случае не создавать новую MyCollection, что нарушило бы привязку.Бу-ху.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top