views:

397

answers:

4

I'm having one hell of a time trying to get my databinding to work correctly. I have reason to believe that what I'm trying to accomplish can't be done, but we'll see what answers I get.

I've got a UserControl. This UserControl contains nothing more than a button. Now within the code behind, I've got a property name IsBookmarked. When IsBookmarked is set, code is run that animates the look of the button. The idea is that you click the button and it visually changes. We'll call this UserControl a Bookmark control.

Now I have another control, which we'll call the FormControl. My FormControl contains a child Bookmark control. I've tried to do databinding on my Bookmark control, but it's not working. Here's some code to help you out.

This is the XAML and Loaded event handler of my control. As you can see it contains a child element that is a custom control (bookmark). So once this control loads, it's DataContext is set to an new instance of an Employee object. Silverlight also sets the DataContext property of my child bookmark control to the same instance. I've verified this by debugging. If my parent has a valid DataContext set then why can't my child control (bookmark) property databind to it?

<UserControl ......>
    <q:Bookmark x:Name="BookMarkControl1" IsBookmarked="{Binding IsSiteBookmarked}" />
</UserControl>

public void Control_Loaded(object sender, EventArgs e)
{
    DataContext = new Employee { IsSiteBookmarked = True };

}

This is my custom control below. Obviously it contains more than this, but for readability I've trimmed it down to the property I'm trying to databind to.

//this is the bookmark control. I've included this control within another control, and I'm trying to databind to properties within my parents DataContext
public partial class Bookmark : UserControl
{

    bool _IsBookmarked= false;
    public bool IsBookmarked
    {
        get {return _IsBookmarked;}
        set { 
                 _IsBookmarked= value;
                 SwitchMode(value);
            }
    }

}

UPDATE

Got some javascript errors that I should mention. Firebug reports a AG_E_PARSER_BAD_PROPERTY_VALUE exception. It doesn't seem like my databinding is even working yet.

A: 

Typically when doing databinding to an object you will want to leverage the INotifyPropertyChanged interface and implement that so that the control can properly invalidate it's property value. Unless you use INotifyPropertyChanged with Mode=TwoWay then any code that changes your DataContext's IsSiteBookmarked will have no effect.

nyxtom
One step at a time. I want to first get databinding to work, and then I'll worry about notifications/updates to the property.
Matt
+1  A: 

Make your IsBookmarked property on the Bookmark control a dependency property.

I presume Control_Loaded is a part of your FormControl, in which case I'm not sure you are using DataContext properly. Best double check that.

UPDATE: Yes, you are using the DataContext properly. AG_E_PARSER_BAD_PROPERTY_VALUE indicates you need to make the IsBookmarked property a dependency property, like so:

 Public Property IsBookmarked() As Boolean
    Get
        Return Me.GetValue(IsBookmarkedProperty)
    End Get
    Set(ByVal value As Boolean)
        Me.SetValue(IsBookmarkedProperty, value)
    End Set
End Property

Public Shared ReadOnly IsBookmarkedProperty As DependencyProperty = DependencyProperty.Register("IsBookmarked", GetType(Boolean), GetType(Bookmark), New PropertyMetadata(New PropertyChangedCallback(AddressOf OnIsBookmarkedPropertyChanged)))

Private Shared Sub OnIsBookmarkedPropertyChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    Dim cntrl As Bookmark = TryCast(d, Bookmark)
    cntrl.SetIsBookmarked(e.NewValue)
End Sub

If you only need to store the value for later use, then you don't need to do anything in the OnIsBookmarkedPropertyChanged procedure, But I put some code there as an example anyway.

Good Luck!

BigChrisDiD
Looks like using a DependencyProperty fixed the issue. No more BAD_PROPERTY parsing problems. Still I wonder why Silverlight needs a DependencyProperty to work. At the very least, a compile time error should be thrown. Thanks for the post, and the sample.
Matt
+1  A: 

I don't recall the exact order in which databinding is evaluated (and I'm too lazy to go look it up), but as I recall, it initially happens BEFORE the form's Loaded event fires, and without making the IsBookmarked property a dependency property, or at least using INotifyPropertyChanged, it may have trouble establishing the datacontext appropriately. I'd recommend either implementing INotifyPropertyChanged or making IsBookmarked a dependency property. DataBinding is tough enough to get right in the best of circumstances (see my long, bad-tempered rant about it here), and you'll just be making it more difficult on yourself if you aren't setting up your properties in the way that it expects.

Ken Smith
+1  A: 

The control exposes a IsSiteBookmarked property(which I believe should be a DependencyProperty) but the control is binding to a IsBookmarked which is not shown. Is this intentional? Have you checked your Visual Studio output window for binding errors?

Addition 1: Since you have fixed the typo in your question and added that there is an error being reported.

Start by clearing up the AG_E_PARSER_BAD_PROPERTY_VALUE problem. Is there a line number and start position in the error message? Start looking there. One strategy is to start taking out XAML until there is no longer an error. This will narrow down the offending code.

Running in debug, mode check for binding errors in the output window.

You might want to also post the Employee class code, especially the IsSiteBookmarked property.

DaveB
My bad, I had a typo. I updated the question.
Matt