Nicolas Guillaume
Nicolas Guillaume

Reputation: 8434

Data binding not working, What is wrong? Silverlight WP7

I'm new to Silverlight and I'm trying to use Databinding. This looks simple but it's not working and I can't find why.

In my MainPage.xaml:

<map:Map Name="bing_map" Height="578" Width="480"

         ZoomLevel="{Binding ZoomLevel, Mode=TwoWay}"
         Center="{Binding Center, Mode=TwoWay}"

         CredentialsProvider="{StaticResource BingMapsKey}" />

As you can see, I'm attempting a binding on ZoomLevel and Center.

In my MainPage.xaml.cs

The class inherit from INotifyPropertyChanged

In the constructor:

ZoomLevel = 12.0;
Center = new GeoCoordinate(0, 0);

The properties:

private double _zoom_level;
private double ZoomLevel
{
    get { return _zoom_level; }
    set {
        if (_zoom_level == value) return;
        _zoom_level = value;
        RaisePropertyChanged("ZoomLevel");}
}

private GeoCoordinate _center;
private GeoCoordinate Center
{
    get { return _center; }
    set {
        if (_center == value) return;
        _center = value;
        RaisePropertyChanged("Center"); }
}

public event PropertyChangedEventHandler PropertyChanged;
void RaisePropertyChanged(string propertyName)
{
    var handler = PropertyChanged;
    if (handler != null)
        handler(this, new PropertyChangedEventArgs(propertyName));
}

Am I forgetting something?

Upvotes: 0

Views: 1550

Answers (2)

MichaelS
MichaelS

Reputation: 7103

Try changing the properties to public:

private double _zoom_level;
public double ZoomLevel
{
    get { return _zoom_level; }
    set {
        if (_zoom_level == value) return;
        _zoom_level = value;
        RaisePropertyChanged("ZoomLevel");}
}

private GeoCoordinate _center;
public GeoCoordinate Center
{
    get { return _center; }
    set {
        if (_center == value) return;
        _center = value;
        RaisePropertyChanged("Center"); }
}

And also set the View DataContext: (as Ray mentioned in his answer)

public partial class MainPage
{
    public MainPage()
    {
        this.DataContext = this;
    }
}

It is highly recommended to use the MVVM pattern.

Upvotes: 4

Ray
Ray

Reputation: 46585

In addition to the properties needing to be public (as per MichaelS's answer), bindings reference the object that is set to the control's DataContext (or its parent's DataContext).

So typically you wouldn't have your Window implement INotifyPropertyChanged but you would create another class (normally called a ViewModel) that implements INotifyPropertyChanged and set that to the Window's DataContext.

e.g.

public class MainWindowViewModel : INotifyPropertyChanged
{
    private GeoCoordinate _center;
    public GeoCoordinate Center
    {
        get { return _center; }
        set 
        {
             if (_center == value) return;
             _center = value;
            RaisePropertyChanged("Center"); }
        }

    public event PropertyChangedEventHandler PropertyChanged;
    void RaisePropertyChanged(string propertyName)
    {
        var handler = PropertyChanged;
        if (handler != null)
            handler(this, new PropertyChangedEventArgs(propertyName));
    }
}

Then in your MainPage.xaml.cs you could do something like this

public partial class MainPage
{
    public MainPage(MainWindowViewModel vm)
    {
        this.DataContext = vm;
    }
}

Of course, a quick fix for you might be to just set your DataContext for the page to be itself.

e.g.

public partial class MainPage
{
    public MainPage()
    {
        this.DataContext = this;
    }
}

Upvotes: 3

Related Questions