Silverlight UserControl Custom Property Binding
What is the proper way to implement Custom Properties is Silverlight UserControls?

Every "Page" in Silverlight is technically a UserControl (they are derived from the UserControl class).  When I say UserControl here, I mean a Custom UserControl that will be used inside many different pages in many different scenarios (similar to an ASP.NET UserControl).

I would like the Custom UserControl to support Binding and not rely on the Name of the Property it is binding to, to always be the same.  Instead, I would like the UserControl itself to have a property that the Controls inside the UserControl bind to, and the ViewModels outside the UserControl also bind to.  (please see the example below)

Binding within the UserControl works, Binding within the MainPage works, The Binding I set up between the MainPage and the UserControl does not work.  Specifically this line:

    <myUserControls:MyCustomUserControl x:Name="MyCustomControl2" SelectedText="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200" Height="50" />

example output:  
(coming soon...)


MainPage.xaml

    <UserControl x:Class="SilverlightCustomUserControl.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:myUserControls="clr-namespace:SilverlightCustomUserControl"
        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
      DataContext="{Binding RelativeSource={RelativeSource Self}}">
     <Canvas x:Name="LayoutRoot">
  <StackPanel Orientation="Vertical">
   <TextBlock Text="UserControl Binding:" Width="200"></TextBlock>
   <myUserControls:MyCustomUserControl x:Name="MyCustomControl2" SelectedText="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200" Height="50" />
   <TextBlock Text="MainPage Binding:" Width="200"></TextBlock>
   <TextBox Text="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200"></TextBox>
   <Border BorderBrush="Black" BorderThickness="1">
    <TextBlock Text="{Binding MainPageSelectedText}" Width="200" Height="24"></TextBlock>
   </Border>
  </StackPanel>
 </Canvas>
    </UserControl>


MainPage.xaml.cs

    namespace SilverlightCustomUserControl
    {
     public partial class MainPage : UserControl, INotifyPropertyChanged
     {
      //NOTE: would probably be in a ViewModel
      public string MainPageSelectedText
      {
       get { return _MainPageSelectedText; }
       set
       {
        string myValue = value ?? String.Empty;
        if (_MainPageSelectedText != myValue)
        {
         _MainPageSelectedText = value;
         OnPropertyChanged("MainPageSelectedText");
        }
       }
      }
      private string _MainPageSelectedText;
    
    
      public MainPage()
      {
       InitializeComponent();
      }
    
    
      #region INotifyPropertyChanged Members
    
      public event PropertyChangedEventHandler PropertyChanged;
    
      protected virtual void OnPropertyChanged(string name)
      {
       PropertyChangedEventHandler ph = this.PropertyChanged;
    
       if (ph != null)
        ph(this, new PropertyChangedEventArgs(name));
      }
    
      #endregion
     }
    }

MyCustomUserControl.xaml

    <UserControl
       x:Class="SilverlightCustomUserControl.MyCustomUserControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     DataContext="{Binding RelativeSource={RelativeSource Self}}">
     <Grid>
  <StackPanel>
   <TextBox Text="{Binding SelectedText, Mode=TwoWay}" />
   <Border BorderBrush="Black" BorderThickness="1">
    <TextBlock Text="{Binding SelectedText}" Height="24"></TextBlock>
   </Border>
  </StackPanel>
 </Grid>
    </UserControl>


MyCustomUserControl.xaml.cs

    namespace SilverlightCustomUserControl
    {
     public partial class MyCustomUserControl : UserControl
     {
      public string SelectedText
      {
       get { return (string)GetValue(SelectedTextProperty); }
       set { SetValue(SelectedTextProperty, value); }
      }
    
      public static readonly DependencyProperty SelectedTextProperty =
        DependencyProperty.Register("SelectedText", typeof(string), typeof(MyCustomUserControl), new PropertyMetadata("", SelectedText_PropertyChangedCallback));
    
    
      public MyCustomUserControl()
      {
       InitializeComponent();
      }
    
      private static void SelectedText_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
       //empty
      }
     }
    }


References (how I got this far):  

use DependencyPropertys:
[http://geekswithblogs.net/thibbard/archive/2008/04/22/wpf-custom-control-dependency-property-gotcha.aspx][1]

use DependencyPropertys, add x:Name to your UserControl - add Binding with ElementName, set Custom property again in the PropertyChangedCallback method:
[http://stackoverflow.com/questions/845564/setting-custom-properties-in-usercontrol-via-databinding][2]


don't use custom properties, rely on underlying datacontext names (I do not like this solution):
[http://stackoverflow.com/questions/1145435/wpf-trouble-using-dependency-properties-in-a-usercontrol][3]


  [1]: http://geekswithblogs.net/thibbard/archive/2008/04/22/wpf-custom-control-dependency-property-gotcha.aspx
  [2]: http://stackoverflow.com/questions/845564/setting-custom-properties-in-usercontrol-via-databinding
  [3]: http://stackoverflow.com/questions/1145435/wpf-trouble-using-dependency-properties-in-a-usercontrol
Silverlight UserControl Custom Property Binding
===

What is the proper way to implement Custom Properties is Silverlight UserControls?

Every "Page" in Silverlight is technically a UserControl (they are derived from the UserControl class).  When I say UserControl here, I mean a Custom UserControl that will be used inside many different pages in many different scenarios (similar to an ASP.NET UserControl).

I would like the Custom UserControl to support Binding and not rely on the Name of the Property it is binding to, to always be the same.  Instead, I would like the UserControl itself to have a property that the Controls inside the UserControl bind to, and the ViewModels outside the UserControl also bind to.  (please see the example below)

Binding within the UserControl works, Binding within the MainPage works, The Binding I set up between the MainPage and the UserControl does not work.  Specifically this line:

    <myUserControls:MyCustomUserControl x:Name="MyCustomControl2" SelectedText="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200" Height="50" />

example output:  
(coming soon...)


MainPage.xaml

    <UserControl x:Class="SilverlightCustomUserControl.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:myUserControls="clr-namespace:SilverlightCustomUserControl"
        mc:Ignorable="d" d:DesignWidth="640" d:DesignHeight="480"
      DataContext="{Binding RelativeSource={RelativeSource Self}}">
     <Canvas x:Name="LayoutRoot">
  <StackPanel Orientation="Vertical">
   <TextBlock Text="UserControl Binding:" Width="200"></TextBlock>
   <myUserControls:MyCustomUserControl x:Name="MyCustomControl2" SelectedText="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200" Height="50" />
   <TextBlock Text="MainPage Binding:" Width="200"></TextBlock>
   <TextBox Text="{Binding MainPageSelectedText, Mode=TwoWay}" Width="200"></TextBox>
   <Border BorderBrush="Black" BorderThickness="1">
    <TextBlock Text="{Binding MainPageSelectedText}" Width="200" Height="24"></TextBlock>
   </Border>
  </StackPanel>
 </Canvas>
    </UserControl>


MainPage.xaml.cs

    namespace SilverlightCustomUserControl
    {
     public partial class MainPage : UserControl, INotifyPropertyChanged
     {
      //NOTE: would probably be in a ViewModel
      public string MainPageSelectedText
      {
       get { return _MainPageSelectedText; }
       set
       {
        string myValue = value ?? String.Empty;
        if (_MainPageSelectedText != myValue)
        {
         _MainPageSelectedText = value;
         OnPropertyChanged("MainPageSelectedText");
        }
       }
      }
      private string _MainPageSelectedText;
    
    
      public MainPage()
      {
       InitializeComponent();
      }
    
    
      #region INotifyPropertyChanged Members
    
      public event PropertyChangedEventHandler PropertyChanged;
    
      protected virtual void OnPropertyChanged(string name)
      {
       PropertyChangedEventHandler ph = this.PropertyChanged;
    
       if (ph != null)
        ph(this, new PropertyChangedEventArgs(name));
      }
    
      #endregion
     }
    }

MyCustomUserControl.xaml

    <UserControl
       x:Class="SilverlightCustomUserControl.MyCustomUserControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
     DataContext="{Binding RelativeSource={RelativeSource Self}}">
     <Grid>
  <StackPanel>
   <TextBox Text="{Binding SelectedText, Mode=TwoWay}" />
   <Border BorderBrush="Black" BorderThickness="1">
    <TextBlock Text="{Binding SelectedText}" Height="24"></TextBlock>
   </Border>
  </StackPanel>
 </Grid>
    </UserControl>


MyCustomUserControl.xaml.cs

    namespace SilverlightCustomUserControl
    {
     public partial class MyCustomUserControl : UserControl
     {
      public string SelectedText
      {
       get { return (string)GetValue(SelectedTextProperty); }
       set { SetValue(SelectedTextProperty, value); }
      }
    
      public static readonly DependencyProperty SelectedTextProperty =
        DependencyProperty.Register("SelectedText", typeof(string), typeof(MyCustomUserControl), new PropertyMetadata("", SelectedText_PropertyChangedCallback));
    
    
      public MyCustomUserControl()
      {
       InitializeComponent();
      }
    
      private static void SelectedText_PropertyChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
       //empty
      }
     }
    }


References (how I got this far):  

use DependencyPropertys:
[http://geekswithblogs.net/thibbard/archive/2008/04/22/wpf-custom-control-dependency-property-gotcha.aspx][1]

use DependencyPropertys, add x:Name to your UserControl - add Binding with ElementName, set Custom property again in the PropertyChangedCallback method:
[http://stackoverflow.com/questions/845564/setting-custom-properties-in-usercontrol-via-databinding][2]


don't use custom properties, rely on underlying datacontext names (I do not like this solution):
[http://stackoverflow.com/questions/1145435/wpf-trouble-using-dependency-properties-in-a-usercontrol][3]


  [1]: http://geekswithblogs.net/thibbard/archive/2008/04/22/wpf-custom-control-dependency-property-gotcha.aspx
  [2]: http://stackoverflow.com/questions/845564/setting-custom-properties-in-usercontrol-via-databinding
  [3]: http://stackoverflow.com/questions/1145435/wpf-trouble-using-dependency-properties-in-a-usercontrol