8

我需要在代码中定义新的 UI 元素以及数据绑定,因为它们将在运行时之后实现。这是我正在尝试做的简化版本。

数据模型:

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

代码绑定:

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

首次绑定数据时,文本块将更新为正确的门牌号。然后,如果我稍后在代码中更改门牌号,则会触发该书的 PropertyChanged 事件,但不会更新文本块。谁能告诉我为什么?

谢谢,本

4

6 回答 6

10

它的根源是我传递给 PropertyChangedEventArgs 的字符串与属性名称不完全匹配。我有这样的事情:

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

它应该在哪里:

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

哎呀!感谢您朝着正确的方向推动。

于 2009-01-02T12:04:58.920 回答
3

确保您正在更新AddressBook绑定中使用的引用,而不是其他一些AddressBook引用。

我得到以下与您提供的地址簿代码一起使用。

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

后面的代码:

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

请注意,更新代码中使用了相同的引用。

于 2009-01-02T11:38:42.727 回答
2

您是否需要以编程方式设置绑定模式?它可能默认为 OneTime。

于 2009-01-02T11:24:59.150 回答
2

我刚刚剪切+粘贴了您的代码(并添加了一点),它对我来说很好:

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

启动时显示 456,单击按钮使 TextBlock 中的数字递增就好了。

也许您在错误的地方寻找问题的原因?

于 2009-01-02T12:00:49.833 回答
1

您确定要更新与绑定中使用的对象相同的对象吗?乍一看没什么问题,所以检查简单的事情。:)

于 2009-01-02T11:29:19.983 回答
0

是否有任何代码绕过该属性,_houseNumber直接设置字段 ( )?

于 2009-01-02T11:30:42.803 回答