Silverlight Method Data Source Markup Extension

A quick way to obtain a data source from a method through a markup extension, without any code:

<ComboBox ItemsSource="{my:MethodDataSource MethodName=GetItems}"/>

Implementation is simple:

public class MethodDataSourceExtension : DependencyObject, IMarkupExtension<Object>
{
    public static readonly DependencyProperty TargetProperty = DependencyProperty.Register("Target", typeof(Object), typeof(MethodDataSourceExtension), new PropertyMetadata(null));
    public static readonly DependencyProperty ArgumentProperty = DependencyProperty.Register("Argument", typeof(Object), typeof(MethodDataSourceExtension), new PropertyMetadata(null));
 
    public String MethodName { get; set; }
 
    public Object Target
    {
        get { return this.GetValue(TargetProperty); }
        set { this.SetValue(TargetProperty, value); }
    }
 
    public Object Argument
    {
        get { return this.GetValue(ArgumentProperty); }
        set { this.SetValue(ArgumentProperty, value); }
    }
 
    public Object ProvideValue(IServiceProvider serviceProvider)
    {
        var rootObjectProvider = serviceProvider.GetService<IRootObjectProvider>();
        var target = (this.Target ?? rootObjectProvider.RootObject);
        var method = target.GetType().GetMethod(this.MethodName, BindingFlags.Instance | BindingFlags.Static | BindingFlags.Public);
        var args = (this.Argument != null) ? new Object[] { this.Argument } : null;
 
        return method.Invoke((method.IsStatic == true) ? null : target, args);
    }
}

The MethodDataSourceExtension has three properties:

  • MethodName: the name of a method;
  • Target: the optional element from which the data source method will be retrieved; if not specified, the containing control (Page, UserControl, etc) will be used;
  • Argument: an optional argument to the data source method.

Because we might want to use bindings, the MethodDataSourceExtension class inherits from DependencyObject. This allows us to have:

<ComboBox ItemsSource="{my:MethodDataSource MethodName=GetItems, Target={Binding ElementName=SomeControl}}"/>

We can call any method, static or instance, as long as it is public. It can have a single parameter or no parameter at all.

                             

No Comments

Add a Comment

As it will appear on the website

Not displayed

Your website