Even a chimp can write code

Thursday, May 17, 2007

Namescopes in Silverlight

When you start naming things, you quickly realize that you need a method to disambiguate or resolve conflicts between names. When your sister cried out "Mom! Pete flushed the goldfish down the toilet!", your mom knew the "Pete" your sis was referring to was you, not the kid down the street. That's because she used an implicit name scope to infer.

What is a name scope?
Nick Kramer describes a name scope or namescope thusly:
"In almost all programming languages, names are not globally unique, they are unique only relative to other names in the same name scope. In C++ and C#, a name scope is roughly what goes between curly braces -- { }. And in C++ and C#, namescopes nest -- if the compiler can't find the name in the nearest namescope { }, it will look in the containing namescope.

Xaml names have many of the same issues. In <Button Name="foo">, foo is not unique to the whole program, there could be other xaml files with the same name. And you can instantiate that xaml file multiple times (e.g., multiple windows). "


Nick goes on to explain the role namescopes play in WPF. They kinda play a similar role in Silverlight.

Okay so we now know that a namescope is a logical grouping of named elements. Further, the "root" or ownership of a namescope is tied to a specific element and all of its named children fall into that namescope unless a child defines another namescope. This element is considered having the ownership of the namescope.

When do I care?
A namescope is typically created when the root visual is set. Well, in Silverlight there's a couple ways you, the app developer, can create elements in a separate namescope. One way is through a createFromXaml call in Javascript where you set the last parameter to true. The other is when you instantiate a Silverlight 1.1 Alpha control (see the SDK). In the latter case, the ControlBase class constructor makes a call to InitializeFromXaml in System.Windows.Controls.Control - which in a way is the managed equivalent of making a createFromXaml(xaml, createNamescope) call. You can use that approach for your custom controls.

Update: And oh, you also care when you do a FindName(). That method only walks the tree in the namescope of the element on which FindName was called. For instance, of you do rootCanvas.FindName("someElementName") you're searching for "someElementName" in the namescope of the rootCanvas element. Another element with the same name but different namescope is invisible at this time.

What types of namescopes exist?

The namescope created with the root visual is called the default namescope. When you call createFromXaml and tell it to create a namescope this is called a private namescope. If you call createFromXaml and do not create a namescope a temporary namescope is created

All elements content created in the visual tree will reside inside the namescope. Names defined in the namescope will not conflict with other names outside of the namescope.
Silverlight Namescopes
Default namescope
A default namescope is automatically created when the root visual is created. The default namescope can be replaced by resetting the main visual tree.

Private namescope
A private namescope is the permanent name scoping that is created. A private namescope has the restrictions mentioned earlier in that it cannot be dissolved – it is always associated with the element that owns the private namescope. Named/un-named elements can be added/remove from the private namescope though.

Temporary Namescope
A temporary namescope is created any time you call createFromXaml and have an element tree fragment not associated with the main tree. A temporary namescope is different from a private namescope in that when you add the element tree fragment to another tree the temporary namescope is dissolved. This "addition" can be by using a collection's Add method or by setting a property such as a Rectangle's Fill.

Labels: , , , ,

Email this | Bookmark this

43 Comments:

Post a Comment | Home | Inference: my personal blog