views:

4141

answers:

3

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?

A: 

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

Jobi Joy
+2  A: 

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);
chaiguy
I would replace displayNameBinding.Source with a call to this.TryFindResource("PhoneServiceDS") so it's exactly equivalent to his XAML, but otherwise I was about to post a solution just like this.
Robert Macnee
The TryFindResource worked with having the ObjectDataSource declared in XAML. I found that ODS is like making an instance of whatever Object that I want to use, so setting my binding source to PhoneService which I have instantiated already also worked. Thanks!
Jippers
A: 

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.

Daniel Paull