locked
Binding a XAML Object's property, to a code behind DependenyProperty RRS feed

  • Question

  •  Hey all,

     

    I got this piece of code - 

     

    <TextBlock Name="textBlockScore" Text="{Binding Path=Score}" FontSize="20"/>

      

    Score is a Dependency property that is defined inside the code behind of the same class

     like that - 

     

     

            public static readonly DependencyProperty ScoreProp = DependencyProperty.Register("Score", typeof(string), typeof(GamePage), null);

    public string Score
    {
    get { return (string)GetValue(ScoreProp); }
    set { SetValue(ScoreProp, value); }
    }

      for some reason this binding will not work unless I will specify the ElementName of my own page in the binding like this

      

    <TextBlock Name="textBlockScore" Text="{Binding ElementName=GamePage, Path=Score}" FontSize="20"/>

     

    But when I give my XAML page a name I get this warning from Expression Blend - 

    "Using more than one instance of a named userControl may cause errors"

     

    Now besides the fact that it doesn't look nice to name each page, I also get a warning.

    Should I really pay attention to that warning? If not, than is this really the best way?

     

    Thanks for the help!

     

    Friday, March 5, 2010 11:51 AM

Answers

  • As far as I know, there isn't a reliable way to bind from a UserControl child back up to the UserControl in XAML.  If you name the UserControl, as you have done, you can use ElementName binding, but this could lead to naming conflicts down the road if you happen to have more than one instance of the UserControl at a time.  Also, you might be able to use RelativeSource=Self with Path=Parent.Property, but this is also unwise since there are situations where Parent would not be the UserControl.  This leaves two options: code-behind and ControlTemplate.

    In code behind, you simply create the binding in the constructor of the UserControl.  Your binding would be:

    Binding b = new Binding("Score");
    b.Source = this;
    textBlockScore.SetBinding(TextBlock.TextProperty, b);

    The other option is to use a default Style and ControlTemplate.  You would create your page in code behind and inherit from a Silverlight base control (Control, ContentControl, etc.)  In the constructor you set a DefaultStyleKey.  Then you place all of the XAML in generic.xaml.  If you use this method, then you can use Text={Binding Score, RelativeSource={RelativeSource TemplatedParent}} to do your binding.  Control Default Styles and ControlTemplating are heavy but very useful topics.  If you are unfamiliar, some research may be needed.  Here are some links that may help you get started....

    http://www.silverlightshow.net/items/Creating-a-Silverlight-Custom-Control-The-Basics.aspx

    http://msdn.microsoft.com/en-us/library/cc964292%28VS.95%29.aspx

    If you are just looking for a quick fix, I would go with code-behind. Good luck!

    Friday, March 5, 2010 2:53 PM

All replies

  • As far as I know, there isn't a reliable way to bind from a UserControl child back up to the UserControl in XAML.  If you name the UserControl, as you have done, you can use ElementName binding, but this could lead to naming conflicts down the road if you happen to have more than one instance of the UserControl at a time.  Also, you might be able to use RelativeSource=Self with Path=Parent.Property, but this is also unwise since there are situations where Parent would not be the UserControl.  This leaves two options: code-behind and ControlTemplate.

    In code behind, you simply create the binding in the constructor of the UserControl.  Your binding would be:

    Binding b = new Binding("Score");
    b.Source = this;
    textBlockScore.SetBinding(TextBlock.TextProperty, b);

    The other option is to use a default Style and ControlTemplate.  You would create your page in code behind and inherit from a Silverlight base control (Control, ContentControl, etc.)  In the constructor you set a DefaultStyleKey.  Then you place all of the XAML in generic.xaml.  If you use this method, then you can use Text={Binding Score, RelativeSource={RelativeSource TemplatedParent}} to do your binding.  Control Default Styles and ControlTemplating are heavy but very useful topics.  If you are unfamiliar, some research may be needed.  Here are some links that may help you get started....

    http://www.silverlightshow.net/items/Creating-a-Silverlight-Custom-Control-The-Basics.aspx

    http://msdn.microsoft.com/en-us/library/cc964292%28VS.95%29.aspx

    If you are just looking for a quick fix, I would go with code-behind. Good luck!

    Friday, March 5, 2010 2:53 PM
  • Also, you may want to change your DependencyProperty declaration to use ScoreProperty instead of ScoreProp.  This will bring the declaration in line with Dependency Property Naming Convention.
    Friday, March 5, 2010 3:01 PM
  •  Thanks a lot for the thorough and useful answer!

    I'll see which one of the options will fit me best. 

    Saturday, March 6, 2010 2:51 PM