Como forçar uma ligação WPF para atualizar?

112

Eu tenho uma caixa de combinação com fonte de itens anexada usando ligação simples. Existe alguma maneira de atualizar esta ligação depois que a caixa de combinação é carregada?

Techee
fonte
1
O que você quer dizer com ligação simples? Normalmente, quando você usa vinculação, o controle deve ser atualizado automaticamente.
Erno,
12
Techee, sem ofensa, mas acredito que HB merece que sua resposta seja aceita ;-)
Dani
1
@Dani Não tenho certeza se Techee voltará algum dia - seis anos e meio desde que ele se conectou
The Lonely Coder

Respostas:

198

Você pode usar expressões de ligação:

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

Mas, como Blindmeis observou, você também pode disparar notificações de alteração, além disso, se sua coleção for implementada INotifyCollectionChanged(por exemplo, implementada no ObservableCollection<T>), ela será sincronizada, portanto, você não precisa fazer nada disso.

HB
fonte
Não parece fazer nada para mim usando um ListBox.
Jonathan Wood
@JonathanWood: Bem, não consigo adivinhar que tipo de código você tem, incluindo a aparência de sua ligação. A encadernação funciona mesmo em primeiro lugar?
HB
56

se você usa mvvm e sua fonte de itens está localizada em sua VM. apenas chame INotifyPropertyChanged para sua propriedade de coleção quando quiser atualizar.

OnPropertyChanged("YourCollectionProperty");
blindmeis
fonte
7
Esta é a abordagem mais limpa imho.
Ash
Isso deve ser feito sempre que possível, mas deve-se observar que nem sempre é prático. Por exemplo, se você está vinculado a uma porta serial e deseja verificar se está aberta, fechada, a taxa de transmissão, etc, você pode criar uma classe de wrapper em torno da porta serial que implementa INotifyPropertyChanged, mas você terá que manter a porta privada para esse wrapper e, portanto, precisa escrever uma propriedade e método para tudo nessa porta que você usa em outro lugar no projeto para garantir que as propriedades que você está interessado em notificar sempre passam pelo wrapper
Assimilater
8
Além disso, sou um grande fã de usar nameof(YourCollectionProperty)ao invés de uma string literal. Isso evita que os bugs sejam refatorados e é mais explícito o que realmente se pretende. É claro que aqui você não pode usar o CallerMemberNameatributo que é ainda melhor
Assimilador
31

Para adicionar meus 2 centavos, se você deseja atualizar sua fonte de dados com o novo valor de seu Controle, você precisa chamar em UpdateSource()vez de UpdateTarget():

((TextBox)sender).GetBindingExpression(ComboBox.TextProperty).UpdateSource();
ponto Net
fonte
1
Eu gosto mais dessa resposta.
Chopnut
8

Versão amigável de MultiBinding ...

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

Tente usar BindingExpression.UpdateTarget()

Kushal Waikar
fonte
0

Eu estava buscando dados do back-end e atualizei a tela com apenas uma linha de código. Funcionou. Não tenho certeza, por que precisamos implementar a Interface. (Windows 10, UWP)

    private void populateInCurrentScreen()
    {
        (this.FindName("Dets") as Grid).Visibility = Visibility.Visible;
        this.Bindings.Update();
    }
Itzdsp
fonte
This.Bindings.update () atualiza todas as ligações na tela. FYI
Itzdsp
Eu tentei this.Bindings.Update () em um usercontrol em UWP e ele não existe.
James Esh
Sim. E este.Bindings ainda não existe.
James Esh
2
Bindings.Update () está disponível apenas onde as ligações compiladas (x: Bind) são usadas ... e as ligações compiladas estão disponíveis apenas em UWP
Marian Dolinský
Por favor, dê uma olhada no comentário @MarianDolinský. Parece que você tem que vincular de xaml
Itzdsp