2009-01-02 235 views
8

我需要定義新的UI元素以及代碼中的數據綁定,因爲它們將在運行時實現。這是我正在嘗試做的簡化版本。在代碼中定義的WPF數據綁定問題不更新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事件,但文本塊不會更新。誰能告訴我爲什麼?

感謝, 本

+0

您是否嘗試設置斷點以查看它們在設置屬性時是否被擊中? – John 2009-01-02 11:24:48

+0

是的,當本書的PropertyChanged事件觸發時,我會彈出一個消息框,這會在每次數據更新時發生。 – 2009-01-02 11:32:55

+0

[最有趣的答案](http:// stackoverflow。com/a/406595/200449),國際海事組織,由@StevenRobbins,雖然是undervoted,然後埋在其他答案 – 2013-04-19 08:04:32

回答

10

它的根源在於我傳遞給PropertyChangedEventArgs的字符串並不完全匹配屬性的名稱。我有這樣的事情:

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

,它應該是這樣的:

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

哎呀!感謝您的正確方向。

2

你需要編程設置結合模式?它可能默認爲OneTime。

+0

感謝您的建議,但增加: bind.Mode = BindingMode.OneWay; 沒有效果。 – 2009-01-02 11:28:24

+0

我可能會誤讀,但聽起來像Beepcake意味着嘗試將BindingMode設置爲BindingMode.TwoWay。 TextBlocks默認是單向的。 – Jab 2009-01-02 17:54:26

+0

有問題的代碼真的沒有設置任何`BindingMode`工作 – 2013-04-19 08:00:25

1

您確定您正在更新綁定中使用的相同對象嗎?乍一看沒有錯,請檢查簡單的事情。 :)

0

是否有任何代碼繞過該屬性,直接設置字段(_houseNumber)?

3

確保您正在更新綁定中使用的AddressBook引用,而不是其他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(); 
    } 
} 

注相同的參考在更新代碼中使用。

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的增量數只精細。

也許您正在尋找問題原因的錯誤地點?