Problema con el enlace de datos WPF definido en el código que no actualiza los elementos de la interfaz de usuario

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

Pregunta

Necesito definir nuevos elementos de la interfaz de usuario, así como el enlace de datos en el código, ya que se implementarán después del tiempo de ejecución. Aquí hay una versión simplificada de lo que estoy tratando de hacer.

Modelo de datos:

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

Encuadernación en 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

Cuando los datos se unen por primera vez, el bloque de texto se actualiza con el número de casa correcto. Luego, si cambio el número de la casa en el código más tarde, el evento PropertyChanged del libro se activa, pero el bloque de texto no se actualiza. ¿Alguien puede decirme por qué?

Gracias, Ben

¿Fue útil?

Solución

La raíz de esto era que la cadena que pasé a PropertyChangedEventArgs no coincidía EXACTAMENTE con el nombre de la propiedad. Tuve algo como esto:

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

Donde debería estar esto:

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

¡Ay! Gracias por el empuje en la dirección correcta.

Otros consejos

Asegúrese de que está actualizando la referencia AddressBook que se utilizó en el enlace, y no otra referencia de AddressBook .

Obtuve lo siguiente para trabajar con el código de la libreta de direcciones que diste.

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

Código detrá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();
    }
}

Tenga en cuenta que se utiliza la misma referencia en el código de actualización.

¿Necesita establecer el modo de enlace programáticamente? Puede que esté por defecto en OneTime.

Acabo de cortar + pegar tu código (y agregar un poco), y funciona bien para mí:

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

Muestra 456 al inicio, al hacer clic en el botón, el número en el incremento de TextBlock está bien.

¿Quizás está buscando en el lugar equivocado la causa del problema?

¿Está seguro de que está actualizando el mismo objeto que ha utilizado en el enlace? A primera vista nada se ve mal, así que revisa las cosas simples. :)

¿Algún código pasa por alto la propiedad, configurando el campo ( _houseNumber ) directamente?

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top