Как заставить обновляться привязку WPF?


112

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


1
Что вы подразумеваете под простой привязкой? Обычно при использовании привязки элемент управления должен автоматически обновляться.
Эрно

13
Techee, без обид, но я считаю, что HB заслуживает того, чтобы его ответ был принят ;-)
Дэни

1
@Dani, я не уверен, что Тичи когда-нибудь вернется - шесть с половиной лет с тех пор, как он вошел в систему
Lonely Coder

Ответы:


198

Вы можете использовать выражения привязки:

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
    ((ComboBox)sender).GetBindingExpression(ComboBox.ItemsSourceProperty)
                      .UpdateTarget();
}

Но, как заметил Блиндмейс, вы также можете запускать уведомления об изменениях, кроме того, если ваша коллекция реализуется INotifyCollectionChanged(например, реализована в ObservableCollection<T>), она будет синхронизироваться, поэтому вам не нужно ничего делать из этого.


Похоже, мне ничего не помогает с использованием ListBox.
Джонатан Вуд

@JonathanWood: Ну, я не могу предсказать, какой у вас код, включая то, как выглядит ваша привязка. Обвязка вообще вообще работает?
HB

56

если вы используете mvvm и ваш источник элементов находится в вашем vm. просто вызовите INotifyPropertyChanged для своего свойства коллекции, когда хотите обновить.

OnPropertyChanged("YourCollectionProperty");

7
Имхо это самый чистый подход.
Эш

Это нужно делать по возможности, но следует отметить, что это не всегда практично. Например, если вы привязываетесь к последовательному порту и хотите проверить, открыт ли он, закрыт, скорость передачи данных и т. Д., Вы можете создать класс-оболочку вокруг последовательного порта, который реализует INotifyPropertyChanged, но вам придется оставить порт частным для эту оболочку и, следовательно, необходимо написать свойство и метод для всего на этом порту, который вы используете в другом месте проекта, чтобы гарантировать, что свойства, которые вы хотите уведомить, всегда проходят через оболочку
Assimilater

8
Кроме того, я большой поклонник использования nameof(YourCollectionProperty)буквальной строки. Это предотвращает рефакторинг ошибок и более ясно показывает, что на самом деле задумано. Это, конечно, где вы не можете использовать CallerMemberNameатрибут, который даже лучше
Assimilater

31

Чтобы добавить мои 2 цента, если вы хотите обновить свой источник данных новым значением вашего элемента управления, вам нужно UpdateSource()вместо этого вызвать UpdateTarget():

((TextBox)sender).GetBindingExpression(ComboBox.TextProperty).UpdateSource();

1
Мне этот ответ больше нравится.
Чопнут

8

Версия для MultiBinding ...

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
    BindingOperations.GetBindingExpressionBase((ComboBox)sender, ComboBox.ItemsSourceProperty).UpdateTarget();
}


0

Я получал данные из серверной части и обновлял экран с помощью всего одной строчки кода. Это сработало. Не уверен, зачем нам реализовывать интерфейс. (Windows 10, UWP)

    private void populateInCurrentScreen()
    {
        (this.FindName("Dets") as Grid).Visibility = Visibility.Visible;
        this.Bindings.Update();
    }

This.Bindings.update () обновляет все привязки на экране. К вашему сведению
Itzdsp

Я пробовал this.Bindings.Update () в пользовательском элементе управления в UWP, но его не существует.
Джеймс Эш

Да. А этой привязки до сих пор не существует.
Джеймс Эш

2
Bindings.Update () доступен только там, где используются скомпилированные привязки (x: Bind) ... а скомпилированные привязки доступны только в UWP
Мариан Долинский

Пожалуйста, взгляните на комментарий @ MarianDolinský. Похоже, вам нужно привязать из xaml
Itzdsp
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.