New User?   Join Now     Login            Forgot Password?    
XamlQuery: jQuery for Silverlight  (19820 hits)
 Share this Article
 
Posted by Prabu Arumugam on Jan-05-2010, last updated on Aug-04-2010
Languages: Silverlight, C#

What is XamlQuery?

XamlQuery is a lightweight Silverlight library for rapid web development. It simplifies several tasks like page/document traversing; finding controls by name, type & property value; event handling; animating and much more. In short, what XamlQuery aims to do to Silverlight is similar to what jQuery does to JavaScript.

XamlQuery: The Write Less, Do More, Silverlight Library.

This article gives a summary about XamlQuery and explains some of the core methods that are used by XamlQuery to find parent and child controls in a rendered Silverlight page.

For more comprehensive and updated information on XamlQuery, visit XamlQuery project page.
You can download XamlQuery from CodePlex.
The latest stable release of XamlQuery is v1.1

Using XamlQuery

XamlQuery provides the following methods for finding 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 techniques used by these methods are explained in detail in the section "How XamlQuery Works?" below or XamlQuery project page.

The ControlSet

All the methods of XamlQuery returns ControlSet object. The ControlSet class is used to hold the set of controls returned by XamlQuery methods. 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. The methods of ControlSet are explained in detail in XamlQuery project page.

Filter Methods

These methods reduce the set of matched controls to those that pass a criteria (defined by the method).

  • FilterByType() - finds and returns controls of specified type.
  • FilterByTypes() - finds and returns controls of specified types.
  • FilterByProperty() - finds and returns controls whose property value matches a specified criteria.
  • RemoveByType() - removes controls of specified type.
  • RemoveByTypes() - removes controls of specified types.
  • Not() - removes the given list of controls.
  • Even() - returns controls at even indices.
  • Odd() - returns controls at odd indices.
  • Gt() - returns controls at index greater than specified index.
  • Lt() - returns controls at index lesser than specified index.
  • Enabled() - returns all enabled controls.
  • Disabled() - returns all disabled controls.
  • Visible() - returns all visible controls.
  • Invisible() - returns all invisible controls.
  • Checked() - returns all checked controls.
  • Unchecked() - returns all unchecked controls.

Value-Related Methods

These methods operate on property values.

  • SetValue() - sets the value of specified property (of all controls) to a given value.
  • GetValue() - returns the value of specified property (of all controls) as List object.
  • SetBinding() - attaches a binding to specified property (of all controls).
  • ClearValue() - clears the local value of a specified property (of all controls).
  • Val() - returns the current value of first control.
  • Data() - gets or sets an arbitrary object to all controls (similar to multiple Tag properties).

Visibility-Related Methods

These methods are used to hide/show controls, with optional animation. The speed of animation and the opacity can be specified through arguments.

  • Hide() - hides all controls.
  • Show() - displays all controls.
  • Toggle() - alternates the visibility of controls.
  • FadeOut() - hides the controls by fading them to transparent.
  • FadeIn() - displays the controls by fading them to opaque.
  • FadeTo() - sets the opacity of controls to a specified value.
  • FadeToggle() - alternates the transparency of controls.
  • SlideUp() - hides the controls with a sliding motion.
  • SlideDown() - displays the controls with a sliding motion.
  • SlideTo() - sets the height of controls to a specified value.
  • SlideToggle() - displays or hides the controls with a sliding motion.

Animation Methods

These methods are used to carry out a custom animation on a given property.

  • Animate() - animates the controls on a given property and settings (like duration, begin/end values, etc.)

Event-Related Methods

These methods simplifies the tasks related to event-handling. The events can be specified by high-level event names, defined by EventType enumeration. For more information, see XamlQuery project page.

  • AddHandler() - attaches an event handler to specified event of all controls.
  • RemoveHandler() - removes the specified event from all controls.
  • Bind() - attaches an event handler to event specified by a high level name. Events attached using Bind() can be fired manually.
  • Trigger() - fires/invokes the event handler of specified event manually (without actual event occurs).

Layout-Related Methods

These methods operate on layout attributes like position, size, etc.

  • Detach() - deletes/removes all controls from the rendered output.
  • DetachByType() - deletes/removes controls of given type from the rendered output.
  • DetachByTypes() - deletes/removes controls of given types from the rendered output.
  • Empty() - removes all controls from a container control (like Panel, Grid, etc.)
  • Width() - returns the actual width of first control.
  • Height() - returns the actual height of first control.
  • Position() - returns the position of first control, with reference to its immediate parent.

Examples of XamlQuery

The following are some examples on the usage of XamlQuery.

//hide all lines
XamlQuery.ByType<Line>(MainCanvas).Hide();

//disable all textboxes
XamlQuery.ByType<TextBox>(RegisterGrid).SetValue(Control.IsEnabledProperty, false);

//remove border of all textboxes
XamlQuery.ByType<TextBox>(RegisterGrid).SetValue(Control.BorderBrushProperty, new SolidColorBrush(Colors.Transparent));

//set font-style of all textboxes
XamlQuery.ByType<TextBox>(RegisterGrid).SetValue(Control.FontStyleProperty, FontStyles.Italic);

//change IsTabStop and Foreground of all hyperlinks
XamlQuery.ByType<HyperlinkButton>(LayoutRoot).SetValue(Control.IsTabStopProperty, false);
XamlQuery.ByType<HyperlinkButton>(LayoutRoot).SetValue(Control.ForegroundProperty, new SolidColorBrush(Colors.Black));

//find all controls with name "ArrowLine"
ControlSet allArrowLines = XamlQuery.ByProperty(MainCanvas, FrameworkElement.NameProperty, "ArrowLine");

The following demo illustrates some animation and style related tasks using a Canvas control.

The event-handler of the buttons in this demo are shown below.

private void ChangeStyleButton_Click(object sender, RoutedEventArgs e)
{
    //find all rectangles inside "MainCanvas"
    ControlSet allShapes = XamlQuery.ByType<Rectangle>(MainCanvas);
    
    //set style for all rectangles
    allShapes.SetValue(Shape.StrokeThicknessProperty, 4.0);
    allShapes.SetValue(Shape.FillProperty, new SolidColorBrush(Colors.LightGray));
    allShapes.SetValue(Rectangle.RadiusXProperty, 8.0);
    allShapes.SetValue(Rectangle.RadiusYProperty, 8.0);
    
    //set mouse-enter event for all rectangles
    allShapes.Bind(EventType.MouseEnter, new MouseEventHandler(delegate(object senderObject, MouseEventArgs eventArgs)
    {
        Rectangle rectangle = (Rectangle)senderObject;
        rectangle.SetValue(Shape.FillProperty, new SolidColorBrush(Colors.Green));
    }));
}

private void ToggleFadeButton_Click(object sender, RoutedEventArgs e)
{
    XamlQuery.ByType<Rectangle>(MainCanvas).FadeToggle(Speed.Fast);
}

private void ToggleSlideButton_Click(object sender, RoutedEventArgs e)
{
    XamlQuery.ByType<Rectangle>(MainCanvas).SlideToggle(Speed.Fast);
}

private void ClearButton_Click(object sender, RoutedEventArgs e)
{
    XamlQuery.All(MainCanvas).Detach();
}

How XamlQuery Works?

The following sections explain the techniques used internally by XamlQuery in order to traverse through the runtime (rendered) control tree and accomplish the tasks.

Finding Parent Controls

The AllParents() method of XamlQuery finds all the parents (upto root control) in the rendered Silverlight page.

public static ControlSet AllParents(DependencyObject control)
{
    ControlSet allParents = new ControlSet();

    while (true)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(control);
        if (parent == null) break;
        else
        {
            allParents.Add(parent);
            control = parent;
        }
    }

    return (allParents);
}

The Root() method of XamlQuery is used to find the topmost parent (root) control of the Silverlight tree. The root control will be usually UserControl or Page. This function accepts any control as argument and finds the root control by traversing the whole XAML tree upwards. If a UserControl or Page is embedded within another UserControl or Page, the later will be returned as root.

public static DependencyObject Root(DependencyObject control)
{
    while (true)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(control);
        if (parent == null) return (parent);
        control = parent;
    }
}

The ParentByName() method of XamlQuery is used to find a parent control using its name. This is very useful while using data-templates. Unlike in other traditional markup languages like HTML and ASP.NET, Silverlight allows to have more than one control under a same name (but in different control paths). This function traverses the XAML tree upwards, starting from the given control and returns the first control with a specified name.

public static DependencyObject ParentByName(DependencyObject control, string parentName)
{
    while (true)
    {
        DependencyObject parent = VisualTreeHelper.GetParent(control);
        if (parent is FrameworkElement && ((FrameworkElement)parent).Name.Equals(parentName)) return (parent);
        else if (parent == null) return (null);
        control = parent;
    }
}

Finding Child Controls by Name and Type

The following class ChildrenFinder is an internal class of XamlQuery, used to recursively find all child controls or to find all child controls by a given type. For example, you can find all text-boxes or labels inside a control and its data-templates / control-templates. The search is performed in all sub-trees of the specified-control. Also, the All and FindByType functions in this class are good examples of using recursion in tree traversal.

public class ChildrenFinder
{
    public List<DependencyObject> Children { get; set; }
	
    public ChildrenFinder()
    {
        this.Children = new List<DependencyObject>();
    }
	
    public void All(DependencyObject control)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(control);
        for (int childIndex = 0; childIndex < childrenCount; childIndex++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(control, childIndex);
            this.Children.Add(child);
            All(child);
        }
    }

    public void FindByType<T>(DependencyObject control)
    {
        int childrenCount = VisualTreeHelper.GetChildrenCount(control);
        for (int childIndex = 0; childIndex < childrenCount; childIndex++)
        {
            DependencyObject child = VisualTreeHelper.GetChild(control, childIndex);
            if (child is T)
            {
                this.Children.Add(child);
            }
            FindByType<T>(child);
        }
    }
}

You can download XamlQuery from CodePlex.


 Downloads for this article
File Language Tools
No files available for download in this article.

 Share this Article

 Comments on this Article
Comment by flame on Dec-17-2013
it usefull
Comment by hoangnguyenlien on Apr-18-2012
good!
Comment by Houdini on Feb-29-2012
nice, this looks promising. Well done! By the way...if you click on the Toggle Slide while it's going up, when it comes back down it wont pass that point..sorry, I just had to break something.
Comment by Deepak Reja on Aug-25-2010
Good
Comment by Valeriano Cossu on Aug-22-2010
Good job!
 Post your comment here
Your Name
Your Email
Comment
Post Comment

About      Terms      Contact