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

あなたが与えた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

私はあなたのコードをカットアンドペーストしました(そして少し追加しました)、そしてそれは私にとってうまくいきます:

    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 に答える
2

バインド モードをプログラムで設定する必要がありますか? OneTime にデフォルト設定されている可能性があります。

于 2009-01-02T11:24:59.150 に答える
1

バインディングで使用したものと同じオブジェクトを更新していますか? 一見問題ないように見えるので、簡単なことを確認してください。:)

于 2009-01-02T11:29:19.983 に答える
0

_houseNumberプロパティをバイパスして、フィールド ( ) を直接設定するコードはありますか?

于 2009-01-02T11:30:42.803 に答える