0

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?

halfer
  • 19,824
  • 17
  • 99
  • 186
Nicolas Guillaume
  • 8,160
  • 6
  • 35
  • 44

2 Answers2

4

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.

Community
  • 1
  • 1
MichaelS
  • 7,023
  • 10
  • 51
  • 75
  • Well I was hoping so hard that it was going to work... But it didn't :/ Thanks anyway. – Nicolas Guillaume Oct 04 '11 at 16:15
  • 1
    @Niklaos: Ray is right, you should also set the Datacontext. It is recommended to use the MVVM pattern. I've edited the answer as well. – MichaelS Oct 04 '11 at 16:20
  • Thanks it was that! I read somewhere that the data context was automatically set to this on the the root... but it looks like it was a lie (like the cake). – Nicolas Guillaume Oct 04 '11 at 16:46
3

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;
    }
}
Ray
  • 45,695
  • 27
  • 126
  • 169