Skip Navigation LinksHome > View Post
Workaround for missing ElementName in Silverlight 2.0 Binding

It's pretty simple and takes advantage of Silverlight 2.0's TwoWay databinding and support for INotifyPropertyChanged. In fact its so simple, you probably guessed it already...

We'll start by creating a simple class with a single property (Value) that implements INotifyPropertyChanged:

public class BindingHelper : INotifyPropertyChanged
{
    private object _value;

    public object Value
    {
        get { return _value; }
        set
        {
            _value = value;
            OnPropertyChanged("Value");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

Easy peasy. Now we just need to create an instance of this chap as static resource in our silverlight application. Then, we bind each element that we want to connect to our resources property, like so:

<StackPanel Margin="5" Background="White">
    <StackPanel.Resources>
        <src:BindingHelper x:Key="bindingHelper" />
    </StackPanel.Resources>
    <TextBox Text="{Binding Value, Source={StaticResource bindingHelper}}" />
    <Slider Value="{Binding Value, Source={StaticResource bindingHelper}, Mode=TwoWay}" Maximum="100" />
</StackPanel>

ElementName workaround in action

Easy peasy. You can create as many instances of the BindingHelper as you need to create separate hooks. Also, you could create a more strongly typed implementation that uses a double property.

Note in this example only the Slider's binding is specified as TwoWay, meaning the TextBox's binding will default to OneWay and therefore won't update the Slider on loss of focus. If this isn't what you want, just change add ",Mode=TwoWay" to the TextBox's binding.

Josh Post By Josh Twist
12:50 AM
13 Mar 2008

Comments:

Posted by Ruurd Boeke @ 13 Mar 2008 12:57 AM
Hi, loved your previous post. But this one I do not get. I got excited when I saw the title, but I'm not seeing at all how binding to some helper class actually constitutes making up for the missing elementname syntax.
I don't want to bind to another object in the resources, but I want to bind to another element..
What am I missing? Are you going to connect that bindinghelper to the value of the element?

Posted by Joy @ 14 Mar 2008 1:05 AM
Can v use as follows to avoid C# coding?

<StackPanel Margin="5" Background="White">
<StackPanel.Resources>
<TextBox x:Key="bindingHelper" />
</StackPanel.Resources>
<TextBox Text="{Binding Tag, Source={StaticResource bindingHelper}}" />
<Slider Value="{Binding Tag, Source={StaticResource bindingHelper}, Mode=TwoWay}" Maximum="100" />
</StackPanel>

Regards,
Joy

Posted by Josh @ 14 Mar 2008 5:46 AM
@Ruurd,

A workaround is never as good as an ideal solution, that's why it's a workaround but using this BindingHelper you now get exactly the same behaviour as you would if you had ElementName. You've connected the two items, but via a middle-man. When the slider changes it changes the BindingHelper's Value property which fires a PropertyChangedEvent. The TextBox is bound to the Value property, sees the PropertyChangedEvent and responds. Happy days :)

@Joy,

I like it! Feels a little weird but it should work OK. Might be hard to read for someone picking the code up after you've left (what's this textbox for?) but a valid approach nonetheless.

Posted by Joy @ 14 Mar 2008 8:22 AM
TextBox doesnt have any importance .We just need a reference point(object) to bind.We can use object of any class which have a dependency property of correct type.(Eg : Button,ListBox etc..)
I just tried to avoid the c# coding .Thats it :)

Posted by Ben @ 16 Apr 2008 4:22 AM
I've tried using the TextBox option and although it works fine in WPF it dies a death in Silverlight 2. It seems as soon as a value of the Tag is applied (when you either drag the slider or even set a default Tag="50" in the TextBox) it kills the app. Blend seems to correctly reflect the setting a default for the Tag but I'm guessing that is rendering the XAML outside of Silverlight?

Using the help class can also cut out the need for converters, potentially a bit nicer keeping all the code in one place:

private bool _visibilityToggleChecked;
private Visibility _borderVisibility = Visibility.Collapsed;

public bool VisibilityToggleChecked
{
get { return _visibilityToggleChecked; }
set
{
_visibilityToggleChecked = value;
if (value)
{
BorderVisibility = Visibility.Visible;
}
else
{
BorderVisibility = Visibility.Collapsed;
}
OnPropertyChanged("VisibilityToggleChecked");
}
}

public Visibility BorderVisibility
{
get { return _borderVisibility; }
set
{
_borderVisibility = value;
OnPropertyChanged("BorderVisibility");
}
}

and

<ToggleButton Content="CheckMe" IsChecked="{Binding VisibilityToggleChecked, Source={StaticResource bindingHelper}, Mode=TwoWay}" />
<Border Height="200" Background="Red" Visibility="{Binding BorderVisibility, Source={StaticResource bindingHelper}}" />

Post a comment:

Name  

E-mail (never shared)

URL

Comments  

Captcha ImageRefresh Image
What's this?
Enter code above