UPDATE: Silverlight 3 (beta 1 at time of this post) supports ElementName and RelativeSource binding :)  See here.

Silverlight 2 doesn’t support WPF’s ElementName or RelativeSource binding.  The simplest solution is to use a “relay” class and have multiple UI elements binding to it.  There are some great posts about it here, here and here.

If you want to write a very simple relay, here’s a base class that can handle the basic plumbing:

public abstract class MultiBindableBase<TKey> : INotifyPropertyChanged
{
    /// <summary>
    /// Dictionary of bindable properties.
    /// </summary>
    private Dictionary<TKey, object> bindables = new Dictionary<TKey,object>();

    /// <summary>
    /// Gets or sets a child value with the specified key.
    /// </summary>
    /// <value>The value to get or set.</value>
    /// <remarks>Listens for PropertyChanged notifications if the value implements <see cref="INotifyPropertyChanged"/>.</remarks>
    protected object this[ TKey key ]
    {
        get
        {
            return bindables.ContainsKey( key )
                ? bindables[ key ]
                : bindables[ key ] = null;
        }

        set
        {
            if ( bindables.ContainsKey( key ) )
            {
                var oldNotify = bindables[ key ] as INotifyPropertyChanged;
                if ( oldNotify != null ) oldNotify.PropertyChanged -= OnNotifyPropertyChanged;
            }

            bindables[ key ] = value;

            var notify = value as INotifyPropertyChanged;
            if ( notify != null ) notify.PropertyChanged += OnNotifyPropertyChanged;

            OnPropertyChanged( key );
        }
    }

    /// <summary>
    /// Called when a property of a child value changes.
    /// </summary>
    /// <param name="sender">The sender.</param>
    /// <param name="e">The <see cref="System.ComponentModel.PropertyChangedEventArgs"/> instance containing the event data.</param>
    private void OnNotifyPropertyChanged( object sender, PropertyChangedEventArgs e )
    {
        foreach( var bindable in bindables )
        {
            if ( bindable.Value == sender )
            {
                OnPropertyChanged( bindable.Key );
                break;
            }
        }
    }

    /// <summary>
    /// Raises the PropertyChanged event for the specified key.
    /// </summary>
    /// <param name="key">The key.</param>
    protected void OnPropertyChanged( TKey key )
    {
        OnPropertyChanged( GetPropertyName( key ) );
    }

    /// <summary>
    /// Gets the name of a child property.
    /// </summary>
    /// <param name="key">The key.</param>
    /// <returns>Returns the name of the specified child property.</returns>
    protected abstract string GetPropertyName( TKey key );

    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    /// <summary>
    /// Raises the PropertyChanged event for the specified property name.
    /// </summary>
    /// <param name="propertyName">Name of the property.</param>
    protected void OnPropertyChanged( string propertyName )
    {
        if ( PropertyChanged != null ) PropertyChanged( this, new PropertyChangedEventArgs( propertyName ) );
    }

    #endregion
}

It’ll raise its own PropertyChanged events for values you assign, or if those values raise their own PropertyChanged events (if they implement INotifyPropertyChanged).  Here’s a trivial single-property implementation:

public class DependencyValue : MultiBindableBase<int>
{
    public object Value
    {
        get { return this[ 0 ]; }
        set { this[ 0 ] = value; }
    }

    protected override string GetPropertyName( int key )
    {
        return "Value";
    }
}

You could use this as a StaticResource in your XAML, perhaps to make a list of items share a common width (in the snippet below, assume “sharedWidth.Value” is set in code-behind to a calculated value):

<Border x:Name="tooltip" BorderBrush="SteelBlue" CornerRadius="10" Background="#D0FFFFFF" Padding="10" Opacity="0">
    <Border.Resources>
        <local:DependencyValue x:Key="sharedWidth"/>
    </Border.Resources>
    <StackPanel>
        <StackPanel Orientation="Horizontal">
            <TextBlock Text="Age" Width="{Binding Value, Source={StaticResource sharedWidth}}" FontSize="9" TextAlignment="Right" Margin="0,0,5,0"/>
            <TextBlock x:Name="tooltipXValue" FontSize="9" FontWeight="Bold"/>
        </StackPanel>
        <ItemsControl x:Name="tooltipContent">
            <ItemsControl.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Title}" Width="{Binding Value, Source={StaticResource sharedWidth}}" FontSize="9" TextAlignment="Right" Margin="0,0,5,0"/>
                        <TextBlock Text="{Binding TooltipValue, Converter={StaticResource stringFormatConverter}, ConverterParameter=C0}" FontSize="9" FontWeight="Bold"/>
                    </StackPanel>
                </DataTemplate>
            </ItemsControl.ItemTemplate>
        </ItemsControl>
    </StackPanel>
</Border>

Let me know if it’s any use! :)

About these ads