Click here to Skip to main content
Click here to Skip to main content
Technical Blog

RegisterName for StoryBoards in WPF (NameScopes)

, 16 Mar 2011 CPOL
Rate this:
Please Sign up or sign in to vote.
RegisterName for StoryBoards in WPF (NameScopes)

Have you ever tried to use your Code-Behind extensively in WPF rather than using XAML to design your objects? Certainly, there is no way you would like to do this when you have an option to avoid, but sometimes it is almost necessary to do such code.

You may argue, even you are smart enough to deal with such a situation yourself using DataTemplates and Resources and make your application truly data driven. Yes it is possible, MVVM addresses such situations, but as I must say it is not always a silver bullet to address situations like this, it is more likely you might device your work more in code. Yes, even if you ask me, I am also less comfortable in code to do the same design as I am in XAML.

Today, one of my pals asked me the code which would add some Random Ellipse in a black Canvas and these points will also move in the screen using a DoubleAnimation. As far as my initial thought is concerned, the code seemed good to me. The code looks like:

public void CreateRandomStars()
{
    int Width = (int)MyCanvas.Width;
    int Height = (int)MyCanvas.Height;

    Random Rnx = new Random(0);

    for (int i = 0; i < 300; i++)
    {
        double Lx = (double)Rnx.Next(Width);
        double Ty = (double)Rnx.Next(Height);
        //starPoints.Add(Ty);
        Ellipse es = new Ellipse();
        es.Name = "es_" + i.ToString(); //setting names dynamically for each
        //ellipse

        es.Width = 2;
        es.Height = 2;

        es.Fill = Brushes.WhiteSmoke;
        es.SetValue(Canvas.LeftProperty, Lx);
        es.SetValue(Canvas.TopProperty, Ty);

        MyCanvas.Children.Add(es);

        DoubleAnimation dAnim = new DoubleAnimation();
        dAnim.From = Ty;
        dAnim.To = Height;
        dAnim.Duration = new Duration(new TimeSpan(0, 0, 5));
        Storyboard.SetTargetName(dAnim, es.Name);
        Storyboard.SetTargetProperty(dAnim, new PropertyPath(Canvas.TopProperty));
               
        MyStoryBoard.Children.Add(dAnim);
    }
}

It adds the controls in a black canvas:

<Canvas Name="MyCanvas" Background="Black" Height="310" Width="500">
        <Canvas.Triggers>
            <EventTrigger RoutedEvent="Canvas.Loaded">
                <BeginStoryboard>
                    <Storyboard RepeatBehavior="Forever" Name="MyStoryBoard">
                    </Storyboard>
                </BeginStoryboard>
            </EventTrigger>
        </Canvas.Triggers>
    </Canvas>

Well, you might think the code will run fine, but it actually won't.

Every control in WPF needs to be registered with its Scope after the object is created so that any other object within the same scope can have access to the object. In the code above, the registration of code is not done before it is actually accessed by the StoryBoard.

MyCanvas.Children.Add(es);
this.RegisterName(es.Name, es);

After I add the line RegisterName for the control, the code worked fine. Hence you should remember that you should use RegisterName for a control before you address the name as Target of another control, especially StoryBoards.

Why Do You Need RegisterName ?

Each WPF control is actually using Namescopes, to uniquely identify one element inside a scope. Each scope generally defines a Table which gets an entry when a control Name is registered, and deleted when it is Unregistered. Any control in WPF which allows child controls needs to implement from INameScope interface to make a common scope for the control such that you can register the same name twice in two scopes but you cannot inside the same scope. Hence WPF allows you to

The concept is much like OOPS where objects can be of the same name in the same scope. But how does WPF achieve this.

Each FrameworkElement derives from INameScope which maintains a HashTable to hold all the registered names, such that when you invoke container.RegisterName(), the name will be automatically checked into the HashTable and assigned. Animation extensively uses the INameScope interface to determine the object at runtime which is set to its Target. Hence to point to the actual object, you need to Register the control which needed to be accessed by StoryBoards.

If you look into container.RegisterName module, it looks like:

Here a HybridDictionary is used, which eventually maintains a HashTable. When one name is registered, the object gets added against the Name into the HashTable and eventually when the object is accessed from the StoryBoards, it eventually points to the actual object from the Table. The same is true for any INameScope controls.

Conclusion

That's it. I hope this post will help you.

Thank you.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Abhishek Sur
Architect
India India
Did you like his post?
 
Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.
 
Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook
 
Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.
 
Presently he is working in WPF, a new foundation to UI development, but mostly he likes to work on architecture and business classes. ASP.NET is one of his strength as well.
Have any problem? Write to him in his Forum.
 
You can also mail him directly to abhi2434@yahoo.com
 
Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com
 
Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralMy vote of 5 PinmemberJaikrishan1-Jun-12 3:52 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.141216.1 | Last Updated 16 Mar 2011
Article Copyright 2011 by Abhishek Sur
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid