Pergunta

Eu preciso definir novos elementos de interface do usuário, bem como a ligação de dados em código, porque eles vão ser implementada após run-time. Aqui está uma versão simplificada do que estou tentando fazer.

Modelo de Dados:

public class AddressBook : INotifyPropertyChanged
{
    private int _houseNumber;
    public int HouseNumber
    {
        get { return _houseNumber; }
        set { _houseNumber = value; NotifyPropertyChanged("HouseNumber"); }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(string sProp)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(sProp));
        }
    }
}

Binding no código:

AddressBook book = new AddressBook();
book.HouseNumber = 123;
TextBlock tb = new TextBlock();
Binding bind = new Binding("HouseNumber");
bind.Source = book;
bind.Mode = BindingMode.OneWay;
tb.SetBinding(TextBlock.TextProperty, bind); // Text block displays "123"
myGrid.Children.Add(tb);
book.HouseNumber = 456; // Text block displays "123" but PropertyChanged event fires

Quando os dados são primeiro limite, o bloco de texto é atualizado com o número da casa correta. Então, se eu mudar o número da casa no código mais tarde, incêndios PropertyChanged evento do livro, mas o bloco de texto não é atualizado. Alguém pode me dizer por quê?

Obrigado, Ben

Foi útil?

Solução

A raiz de tudo é que a string I passado para PropertyChangedEventArgs não corresponder exatamente ao nome da propriedade. Eu tinha algo como isto:

public int HouseNumber
{
    get { return _houseNumber; }
    set { _houseNumber = value; NotifyPropertyChanged("HouseNum"); }
}

Onde deve ser esta:

public int HouseNumber
{
    get { return _houseNumber; }
    set { _houseNumber = value; NotifyPropertyChanged("HouseNumber"); }
}

Caramba! Agradecimentos para o impulso na direção certa.

Outras dicas

Certifique-se de que você está atualizando a referência AddressBook que foi usado na ligação, e não alguma outra referência AddressBook.

Eu tenho o seguinte para o trabalho com o código AddressBook que você deu.

<StackPanel>
    <Button Click="Button_Click">Random</Button>
    <Grid x:Name="myGrid">
    </Grid>
</StackPanel>

código por trás:

public partial class Window1 : Window
{
    private AddressBook book;

    public Window1()
    {
        InitializeComponent();

        book = new AddressBook();
        book.HouseNumber = 13;

        TextBlock tb = new TextBlock();
        Binding bind = new Binding("HouseNumber");
        bind.Source = book;
        tb.SetBinding(TextBlock.TextProperty, bind);
        myGrid.Children.Add(tb);
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        Random rnd = new Random();
        book.HouseNumber = rnd.Next();
    }
}

Observe a mesma referência é usado no código de atualização.

Você precisa definir o modo de ligação através de programação? Pode ser falta para OneTime.

Acabei de cortar + colou seu código (e acrescentou um pouco), e ele funciona muito bem para mim:

    public Window1()
    {
        InitializeComponent();

        AddressBook book = new AddressBook();
        book.HouseNumber = 123;
        TextBlock tb = new TextBlock();
        Binding bind = new Binding("HouseNumber");
        bind.Source = book;
        bind.Mode = BindingMode.OneWay;
        tb.SetBinding(TextBlock.TextProperty, bind); // Text block displays "123"
        myGrid.Children.Add(tb);
        book.HouseNumber = 456; 
    }

    private void TestButton_Click(object sender, RoutedEventArgs e)
    {
        AddressBook book = 
           (AddressBook(TextBlock)
              myGrid.Children[0])
              .GetBindingExpression(TextBlock.TextProperty)
              .DataItem;

        book.HouseNumber++;
    }

Exibe 456 no arranque, clicando no botão faz com que o número no incremento TextBlock muito bem.

Talvez você esteja procurando no lugar errado para a causa do problema?

Você tem certeza de que você está atualizando o mesmo objeto que você usou na ligação? À primeira vista, nada parece errado, de modo a verificar as coisas simples. :)

Será que algum código de bypass da propriedade, definindo o campo (_houseNumber) diretamente?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top