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.

Tags: Silverlight

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

» Next Post: Invoking a Command on a Double Click (or other 'Mouse Gesture')
« Previous Post: First look at Binding in Silverlight 2.0 Beta 1

Comments are closed for this post.

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}}" />

Posted by Tony @ 20 Nov 2008 11:19 AM
This is great and it's working out for everything I've used it on except for dependency properties you create on your own controls. For example, create a usercontrol with a dependency property. Now bind to that property. I get an AG_E_PARSER_BAD_PROPERTY_VALUE. When I do this. I've even changed the "object" type on the BindingHelper class to the same type as the dependency property on the usercontrol and I still get the same error. It strangely weird!

Posted by Tony @ 20 Nov 2008 11:29 AM
Ah! I just found this out that "Binding in Silverlight must be a FrameworkElement". I'll try and find a workaround for the workaround.

Posted by Kevin Babcock @ 03 Apr 2009 6:26 AM
Excellent tip! Thanks for sharing!

Posted by Rock @ 08 Dec 2010 9:44 AM
hi,

how to change the visiblity of a usercontrol in the same event in WPF...

I tried the below code,but its not working..

private void button1_Click(object sender, RoutedEventArgs e)
{
UserControl1.Visibility = Visibility.Visible;
//some function wich takes time for around 20 secs
UserControl1.Visibility = Visibility.Collapsed;
}

please suggest me any ideas

Posted by Josh @ 08 Dec 2010 4:20 PM
All the work there will be in the same dispatcher packet. You'll just block the UI thread for 20 seconds. You need to learn to use the dispatcher. There's LOTS of resources out there, just search. Sorry, don't have time to write it up for you. Good Luck!

© 2005 - 2014 Josh Twist - All Rights Reserved.