简体   繁体   中英

C# data binding doesn't update WPF

I'm trying to do a Data Binding in the C# code behind rather than the XAML. The XAML binding created in Expression Blend 2 to my CLR object works fine. My C# implementation only updates when the application is started after which subsequent changes to the CLR doesn't update my label content.

Here's the working XAML binding. First a ObjectDataProvider is made in my Window.Resources.

<ObjectDataProvider x:Key="PhoneServiceDS" 
    ObjectType="{x:Type kudu:PhoneService}" d:IsDataSource="True"/>

And the label content binding:

<Label x:Name="DisplayName" Content="{Binding 
    Path=MyAccountService.Accounts[0].DisplayName, Mode=OneWay, 
    Source={StaticResource PhoneServiceDS}}"/>

Works great. But we want this set up in C# so we can independently change the XAML (ie. new skins). My one time working C# as follows:

     Binding displayNameBinding = new Binding();
     displayNameBinding.Source = 
         PhoneService.MyAccountService.Accounts[0].DisplayName;
     displayNameBinding.Mode = BindingMode.OneWay;
     this.DisplayName.SetBinding(Label.ContentProperty, displayNameBinding);

This is inside my MainWindow after InitializeComponent();

Any insight why this only works on startup?

Your C# version does not match the XAML version. It should be possible to write a code version of your markup, though I am not familiar with ObjectDataProvider.

Try something like this:

Binding displayNameBinding = new Binding( "MyAccountService.Accounts[0].DisplayName" );
displayNameBinding.Source = new ObjectDataProvider { ObjectType = typeof(PhoneService), IsDataSource = true };
displayNameBinding.Mode = BindingMode.OneWay;
this.DisplayName.SetBinding(Label.ContentProperty, displayNameBinding);

In the priginal code you have confused the source and path.

     Binding displayNameBinding = new Binding();
     displayNameBinding.Source = PhoneService;
     displayNameBinding.Path = "MyAccountService.Accounts[0].DisplayName";
     displayNameBinding.Mode = BindingMode.OneWay;
     this.DisplayName.SetBinding(Label.ContentProperty, displayNameBinding);

(I assume PhoneService is an object instance, otherwise perhaps PhoneService. MyAccountService.Accounts[0] should be the Source?)

From memory, you can pass the path as an argument to the constructor.

Write this inside Loaded event instead of Constructor. Hope you implmented INotifyPropertyChanged triggered on the DisplayName property setter?

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM