Problem with WPF Data Binding Defined in Code Not Updating UI Elements

前端 未结 6 737
天涯浪人
天涯浪人 2021-02-08 22:51

I need to define new UI Elements as well as data binding in code because they will be implemented after run-time. Here is a simplified version of what I am trying to do.

相关标签:
6条回答
  • 2021-02-08 23:26

    Make sure you're updating the AddressBook reference that was used in the binding, and not some other AddressBook reference.

    I got the following to work with the AddressBook code you gave.

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

    Code behind:

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

    Note the same reference is used in the update code.

    0 讨论(0)
  • 2021-02-08 23:28

    Do you need to set the binding mode programatically? It may be defaulting to OneTime.

    0 讨论(0)
  • 2021-02-08 23:30

    Are you sure you're updating the same object as you've used in the binding? At first glance nothing looks wrong, so check the simple things. :)

    0 讨论(0)
  • 2021-02-08 23:35

    The root of it was that the string I passed to PropertyChangedEventArgs did not EXACTLY match the name of the property. I had something like this:

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

    Where it should be this:

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

    Yikes! Thanks for the push in the right direction.

    0 讨论(0)
  • 2021-02-08 23:38

    I've just cut+pasted your code (and added a little), and it works fine for 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++;
        }
    

    Displays 456 on startup, clicking the button makes the number in the TextBlock increment just fine.

    Perhaps you are looking in the wrong place for the cause of the problem?

    0 讨论(0)
  • 2021-02-08 23:47

    Does any code bypass the property, setting the field (_houseNumber) directly?

    0 讨论(0)
提交回复
热议问题