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

112

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

Techee
источник
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>), она будет синхронизироваться, поэтому вам не нужно ничего делать из этого.

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

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

OnPropertyChanged("YourCollectionProperty");
blindmeis
источник
7
Имхо это самый чистый подход.
Эш
Это нужно делать по возможности, но следует отметить, что это не всегда практично. Например, если вы привязываетесь к последовательному порту и хотите проверить, открыт ли он, закрыт, скорость передачи данных и т. Д., Вы можете создать класс-оболочку вокруг последовательного порта, который реализует INotifyPropertyChanged, но вам придется оставить порт частным для эту оболочку и, следовательно, необходимо написать свойство и метод для всего на этом порту, который вы используете в другом месте проекта, чтобы гарантировать, что свойства, которые вы хотите уведомить, всегда проходят через оболочку
Assimilater
8
Кроме того, я большой поклонник использования nameof(YourCollectionProperty)буквальной строки. Это предотвращает рефакторинг ошибок и более ясно показывает, что на самом деле задумано. Это, конечно, где вы не можете использовать CallerMemberNameатрибут, который даже лучше
Assimilater
31

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

((TextBox)sender).GetBindingExpression(ComboBox.TextProperty).UpdateSource();
Dotnet
источник
1
Мне этот ответ больше нравится.
Чопнут
8

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

private void ComboBox_Loaded(object sender, RoutedEventArgs e)
{
    BindingOperations.GetBindingExpressionBase((ComboBox)sender, ComboBox.ItemsSourceProperty).UpdateTarget();
}
Tempeck
источник
6

Попробуйте использовать BindingExpression.UpdateTarget()

Кушал Вайкар
источник
0

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

    private void populateInCurrentScreen()
    {
        (this.FindName("Dets") as Grid).Visibility = Visibility.Visible;
        this.Bindings.Update();
    }
Itzdsp
источник
This.Bindings.update () обновляет все привязки на экране. К вашему сведению
Itzdsp
Я пробовал this.Bindings.Update () в пользовательском элементе управления в UWP, но его не существует.
Джеймс Эш
Да. А этой привязки до сих пор не существует.
Джеймс Эш
2
Bindings.Update () доступен только там, где используются скомпилированные привязки (x: Bind) ... а скомпилированные привязки доступны только в UWP
Мариан Долинский
Пожалуйста, взгляните на комментарий @ MarianDolinský. Похоже, вам нужно привязать из xaml
Itzdsp