Problème lié à la liaison de données WPF définie dans le code qui ne met pas à jour les éléments d'interface utilisateur

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

Question

Je dois définir de nouveaux éléments d'interface utilisateur ainsi qu'une liaison de données dans le code car ils seront implémentés après l'exécution. Voici une version simplifiée de ce que j'essaie de faire.

Modèle de données:

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));
        }
    }
}

Liaison dans le code:

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

Lorsque les données sont liées pour la première fois, le bloc de texte est mis à jour avec le numéro de rue correct. Ensuite, si je modifie ultérieurement le numéro de rue dans le code, l'événement PropertyChanged du livre est déclenché, mais le bloc de texte n'est pas mis à jour. Quelqu'un peut-il me dire pourquoi?

Merci, Ben

Était-ce utile?

La solution

La racine de cela était que la chaîne que j'ai transmise à PropertyChangedEventArgs ne correspond pas EXACTEMENT au nom de la propriété. J'ai eu quelque chose comme ça:

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

Où cela devrait être ceci:

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

beurk! Merci pour la poussée dans la bonne direction.

Autres conseils

Assurez-vous de mettre à jour la référence AddressBook utilisée dans la liaison, et non une autre référence AddressBook .

Les éléments suivants ont été utilisés pour utiliser le code du carnet d'adresses que vous avez fourni.

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

Code derrière:

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();
    }
}

Notez que la même référence est utilisée dans le code de mise à jour.

Avez-vous besoin de définir le mode de reliure par programmation? Il se peut que OneTime soit par défaut.

Je viens de couper + coller votre code (et en ajouter un peu), et cela fonctionne très bien pour moi:

    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++;
    }

Affiche 456 au démarrage, un clic sur le bouton rend le numéro dans l'incrément de TextBlock très bien.

Peut-être cherchez-vous au mauvais endroit la cause du problème?

Êtes-vous sûr de mettre à jour le même objet que celui utilisé dans la liaison? À première vue, rien ne semble faux, alors vérifiez les choses simples. :)

Un code quelconque ignore-t-il la propriété en définissant le champ ( _houseNumber ) directement?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top