Problema con associazione dati WPF definita nel codice che non aggiorna gli elementi dell'interfaccia utente

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

Domanda

Devo definire nuovi elementi dell'interfaccia utente e l'associazione dei dati nel codice perché verranno implementati dopo il runtime. Ecco una versione semplificata di ciò che sto cercando di fare.

Modello di dati:

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

Codice obbligatorio:

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 i dati vengono associati per la prima volta, il blocco di testo viene aggiornato con il numero civico corretto. Quindi, se cambio il numero civico nel codice in un secondo momento, l'evento PropertyChanged del libro viene generato, ma il blocco di testo non viene aggiornato. Qualcuno può dirmi perché?

Grazie, Ben

È stato utile?

Soluzione

La radice era che la stringa che ho passato a PropertyChangedEventArgs non corrispondeva ESATTAMENTE al nome della proprietà. Ho avuto qualcosa del genere:

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

Dove dovrebbe essere questo:

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

Yikes! Grazie per la spinta nella giusta direzione.

Altri suggerimenti

Assicurati di aggiornare il riferimento AddressBook utilizzato nell'associazione e non qualche altro riferimento AddressBook .

Ho ottenuto quanto segue per lavorare con il codice della Rubrica che hai fornito.

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

Codice dietro:

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

Nota: lo stesso riferimento viene utilizzato nel codice di aggiornamento.

È necessario impostare la modalità di associazione a livello di codice? Potrebbe essere impostato su OneTime per impostazione predefinita.

Ho appena tagliato + incollato il tuo codice (e aggiunto un po '), e funziona bene per me:

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

Visualizza 456 all'avvio, facendo clic sul pulsante il numero nell'incremento di TextBlock va bene.

Forse stai cercando la causa del problema nel posto sbagliato?

Sei sicuro di aggiornare lo stesso oggetto che hai usato nell'associazione? A prima vista nulla sembra sbagliato, quindi controlla le cose semplici. :)

Qualche codice ignora la proprietà, impostando direttamente il campo ( _houseNumber )?

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top