When the source of binding is null is not evaluated anymore. Is this a Binding bug?
Last post 05-16-2008 2:17 PM by Lluis. 6 replies.
Sort Posts:
05-10-2008 5:05 AM
When the source of binding is null is not evaluated anymore. Is this a Binding bug?

It's a common scenario  to assign window datacontex to a "controller class".

This contoller class contains properties that are lazy loaded , and therefore instantiated when needed.

If the window is instantiated  before the load , some framework elements are binded to null properties. that never will be updated with loaded data.

This  behavior breaks also WPF compatibility.

Will this be changed in RTM  ? 

 

Lluis

Joined on 04-16-2008
Posts 5
05-13-2008 2:20 AM
Re: When the source of binding is null is not evaluated anymore. Is this a Binding bug?

Hello, can you post some code? I don't see any differences between WPF and Silverlight in this area.

If you have something like this:

public class Data : INotifyPropertyChanged

{

private string test;public string Test

{

get { return test; }

set

{

test =
value;if (PropertyChanged != null)

{

PropertyChanged(
this, new PropertyChangedEventArgs("Test"));

}

}

}

public event PropertyChangedEventHandler PropertyChanged;

}


 

In your main class, initially you have a null Data class:

private Data data;

 

Then you set data to a new instance of the Data class after you set DataContext, it doesn't work in both WPF and Silverlight. This is by design.

this.DataContext = data;

data = new Data() { Test = "aaa" };

 

If, however, your data classes look like this:

public class Data : INotifyPropertyChanged

{

private Nested ne;public Nested Ne

{

get { return ne; }

set

{

ne =
value;if (PropertyChanged != null)

{

PropertyChanged(
this, new PropertyChangedEventArgs("Ne"));

}

}

}

public event PropertyChangedEventHandler PropertyChanged;

}

public class Nested : INotifyPropertyChanged

{

private string test;public string Test

{

get { return test; }

set

{

test =
value;if (PropertyChanged != null)

{

PropertyChanged(
this, new PropertyChangedEventArgs("Test"));

}

}

}

public event PropertyChangedEventHandler PropertyChanged;

}

 

In your main class, you initialized the parent class before you set the DataContext:

private Data data = new Data();

 

And after setting DataContext, you set the nested property to a new object, it works fine in both WPF and Silverlight.

this.DataContext = data;

data.Ne = new Nested() { Test = "aaa" };

shanaolanxing - Please mark the posts as answers if they help and unmark if they don't.

Yi-Lun Luo - MSFT

Joined on 10-29-2007
Posts 1,084
05-14-2008 2:57 PM
Re: When the source of binding is null is not evaluated anymore. Is this a Binding bug?

Hi  Yi-Lun Luo

Try this code:

 XAML:

<Grid x:Name="LayoutRoot" >

 

<StackPanel>

 

 

<TextBlock x:Name="Text1" Text="{Binding InnerData.Test}"/>

 

<Button Content="change" Click="ChangeText"/>

</StackPanel>

 

</Grid>

 

 

 

 

Code Behind: 

-----------------------------------------------

namespace Silver1

{

public class Data : INotifyPropertyChanged

{

private Data innerData;private string test;

 

public string Test

{

get { return test; }

set

{

test =
value;

if (PropertyChanged != null)

PropertyChanged(this, new PropertyChangedEventArgs("Test"));

}

}

public Data InnerData

{

get { return innerData; }

set

{

innerData =
value;

if (PropertyChanged != null)

PropertyChanged(this, new PropertyChangedEventArgs("InnerData"));

}

}

public event PropertyChangedEventHandler PropertyChanged;

}

public partial class Page : UserControl

{

Data data;public Page()

{

       InitializeComponent();

        data =
new Data();

       Text1.DataContext = data;

}

void ChangeText(object sender, RoutedEventArgs e)

{

       data.InnerData.Test =
"This is a Test";     //   ->  TextBox not changed    (but changed with WPF)

}

}

}

 

And if you change your Page constructor with

public Page()

{

       InitializeComponent();

        data = new Data();

       data.InnerData = new Data();   // Initializing nested class

       Text1.DataContext = data;

}

 Then works OK

 

Lluis

Joined on 04-16-2008
Posts 5
05-15-2008 1:01 AM
Re: Re: When the source of binding is null is not evaluated anymore. Is this a Binding bug?

Your first sample doesn't work because data.InnerData is null. You're trying to set a value for null.Test. This will result in a NullReferenceException. Are you sure it works in WPF? In my test, it doesn't work. And it shouldn't work. After all, even without data binding, how can you expect this code working?

Data data = null;

data.Test = "abc";

 

You must initialize InnerData before you can set any properties on it.

void ChangeText(object sender, RoutedEventArgs e)

{

data.InnerData =
new Data();

data.InnerData.Test = "This is a Test"; // -> TextBox not changed (but changed with WPF)

}

 

shanaolanxing - Please mark the posts as answers if they help and unmark if they don't.

Yi-Lun Luo - MSFT

Joined on 10-29-2007
Posts 1,084
05-15-2008 8:29 AM
Re: Re: Re: When the source of binding is null is not evaluated anymore. Is this a Binding bug?

Let me explain:

if I write something like this

<TextBlock x:Name="Text1" Text="{Binding InnerData.Test}"/>

I expect that TextBlok must show  in his Text property  "InnerData.Test" property of his Datacontext.

If Datacontext  InnerData.Test is null , of course  Text must be null.

Then InnerData takes a value -> If dataContext implements INotifyPropertyChanged , the binding must know that must change the value, because InnerData is changing.

Now InnerData  is not null , and Text property must be updated with Test value.

Greetings.

Lluis

Joined on 04-16-2008
Posts 5
05-15-2008 11:55 PM
Re: Re: Re: Re: When the source of binding is null is not evaluated anymore. Is this a Binding bug?

Yes. What's wrong? First with

data = new Data();

data.InnerData is null so the TextBlock displays nothing. Then with

data.InnerData.Test ="This is a Test";

It'll throw a NullReferenceException because data.InnerData is null and thus doesn't have a Test property. If you initialize InnerData:

data.InnerData = new Data();

The TextBlock still displays nothing because at this time data.InnerData.Test is an empty string. Then after you set

data.InnerData.Test ="This is a Test";

The TextBlock will successfully display "This is a Test.". I don't see any problems here. Am I missing something?

shanaolanxing - Please mark the posts as answers if they help and unmark if they don't.

Yi-Lun Luo - MSFT

Joined on 10-29-2007
Posts 1,084
05-16-2008 2:17 PM
Marked as Answer
Re: Re: Re: Re: When the source of binding is null is not evaluated anymore. Is this a Binding bug?

Maybe it's a version problem.   This simple thing donĀ“t work in my system.

Anyway , if this scenario is supported, we can close this thread.

Thanks for your time.

 

 

 

Lluis

Joined on 04-16-2008
Posts 5