XamlQuery provides two approaches for finding controls.
- Using Selector Queries, and
- Using Managed Helper Methods
Using Selector Queries
A selector is a string that contains a set of rules or conditions to find controls. The search is performed in child / descendant controls of a given reference control. Once the syntax and usage are understood, the selectors are very easy and intuitive way to find controls. Selectors are explained in detail in XamlQuery Selectors.
The reference control limits the search scope. It is very important to search in a lesser scope because of Silverlight's behavior of creating additional controls in the rendered output. For example, if a Grid is placed inside a ScrollViewer, Silverlight will create a Rectangle control in between ScrollViewer and Grid.
For instance, if the user needs to find all the rectangles inside a Canvas control, consider the following two lines of code.
The first line will return many unwanted Rectangles, whereas the second line will return controls inside the MainCanvas only. Note the LayoutRoot is the name of root control of the Page or UserControl.
The following method is used to find controls using selectors.
- Search() method accepts a reference control and a selector query-string and returns the matching controls. The reference control is the one where the search starts.
Using Managed Helper Methods
The following are helper methods that are used to find children and parent controls.
- All() finds all children of a given control.
- ByType() finds all children of specified type, for example TextBox, Rectangle, etc.
- ByProperty() finds children whose property value matches a specified criteria. The FilterType optional parameter controls the matching of property value. The possible values for FilterType are Equal, NotEqual, StartsWith, EndsWith and Contains. The string representation of the property value is used for matching.
- AllParents() finds all parents (upto root) of a control.
- ParentsUpto() finds all parents, until the parent with specified name or type is found.
- ParentByType() finds the first parent of specified type.
- ParentsByType() finds all parents of specified type.
- ParentByName() finds a parent control by name.
- Root() method finds the root control in the rendered Silverlight page. If a UserControl or Page is embedded within another UserControl or Page, the later will be returned as root.
The ControlSet is a list of dependency objects. The ControlSet class is used to hold the set of controls returned by XamlQuery methods. That is, all methods of XamlQuery returns ControlSet object. The ControlSet provides several methods/functions for carrying out useful tasks related to the controls. Each method operates on all the controls in the ControlSet. These methods are explained in detail in XamlQuery API section.
Manipulating the ControlSet
Most of the methods of ControlSet simplifies a complex task and can be invoked in a single line. The following example changes the stroke-thickness and stroke-fill properties of all rectangles in a canvas control. This example is illustrated in a live demonstration in Examples and Demos.
XamlQuery.ByType<Rectangle>(MainCanvas).SetValue(Shape.FillProperty, new SolidColorBrush(Colors.LightGray));
These two lines are equivalent to the following:
XamlQuery.Search(MainCanvas, "Rectangle").SetValue(Shape.FillProperty, new SolidColorBrush(Colors.LightGray));
Throughout XamlQuery, the DependencyObject class is used instead of control types, so that any type of Silverlight controls can be used as arguments and return types in XamlQuery. For control-specific operations on ControlSet, each element has to be converted (type casting) to appropriate control type. For example, the following code finds the total length of text in all Textbox controls inside a Grid.
ControlSet allTextBoxes = XamlQuery.ByType<TextBox>(RegisterGrid);
int totalLength = 0;
TextBox textBox = (TextBox)child;
totalLength += textBox.Text.Length;