SIGN UP MEMBER LOGIN:    
ARTICLE

Creating a Custom Markup Extension in WPF

Posted by Mamta M Articles | WPF with C# July 08, 2011
Custom Markup Extension enables you to extend XAML and set any property that can be set in XAML using attribute syntax.
Reader Level:


Markup extensions are placeholders in XAML that are used to resolve a property at runtime. A markup extension enables you to extend XAML and set any property that can be set in XAML using attribute syntax. xNull, x:Array, :StaticResource, and DynamicResource are some common markup extensions.

The System.Windows.Markup namespace defines many of the markup extension classes. These class names end with the suffix Extension; however, you can omit the Extension suffix. For example, in XAML, you represent the NullExtension markup class as x:Null.

A custom markup extension is a class created by extending the MarkupExtension class or the IMarkupExtension interface. It is useful in scenarios where you need to provide functionality or behavior that is beyond the scope of existing built-in markup extensions.

Consider that you want to bind a ListBox that will bind to XML data as shown below but for some reason you don't want to use an ObjectDataProvider.

<ListBox ItemsSource="<some way to bind the data> Source=Books.xml, Path=/Book/Title}"

If you want to declaratively bind as shown above, you will need to use a custom markup extension.

The steps to create and use such an extension are:

  1. Create a WPF application named WPFXMLBinding
  2. Add an XML file named Books to the application that has the following contents:

    <?xml version="1.0" encoding="utf-8" ?>
    <Books>
      <
    Book Title="Coma" Author="Robin Cook" />
      <Book Title="The Color Purple" Author="Alice Walker" />
      <Book Title="The White Tiger" Author="Aravind Adiga" />
      <Book Title="A Thousand Splendid Suns" Author="Khaled Hoseini" />
    </Books>
     
  3. Add reference to System.Xml.Linq assembly.
  4. Using the Project->Add Class menu option, add a class named CustomXMLExtension to the application.
  5. Add the following code to the class:

    namespace WPFXMLBinding
    {
        public class
    CustomXMLExtension
    : MarkupExtension
        {
            public string Source { get; set; }
            public string Path { get; set; }
            private static List<string> Parse(string file, string path)
            {
                XDocument xdoc = XDocument.Load(file);

                string[] text = path.Substring(1).Split('/');
                string desc = text[0].ToString();
                string elementname = text[1].ToString();
                List<string> data = new List<string>();

                IEnumerable<XElement> elems = xdoc.Descendants(desc);
     
                IEnumerable<XElement> elem_list = from elem in elems
                                                  select elem;
                foreach (XElement element in elem_list)
                {
                    String str0 =
                    element.Attribute(elementname).Value.ToString();
                    data.Add(str0);
                }
                return data;
            }
            /// <summary>
            /// Overridden method, returns the source and path to bind to
            /// </summary>
            /// <param name="serviceProvider"></param>
            /// <returns></returns>
            public override object ProvideValue(IServiceProvider
            serviceProvider)
            {
                if ((Source != null) && (Path != null))
                    return Parse(Source, Path);
                else throw new InvalidOperationException("Inputs cannot be blank");
            }
        }
    }

    The CustomXMLExtension class is derived from the MarkupExtension class which is defined in the System.Windows.Markup assembly.

    The MarkupExtension class provides a base class for custom XAML markup extension implementations.
    This class defines a method named ProvideValue() whose syntax is as follows:

    Syntax:

    public abstract Object ProvideValue
    (
    IServiceProvider serviceProvider
    )

    The ProvideValue() method is overridden (or implemented, if inheriting from the interface) in the derived class) and returns an object. This object will become the value of the target property for the markup extension. In the current example, the ProvideValue() method will return an object used as the source for the XML binding.
     

  6. In the MainWindow.xaml, write the XAML markup as shown:

    <Window x:Class="WPFXMLBinding.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    xmlns:local="clr-namespace:WPFXMLBinding">
    <
    Grid x:Name="LayoutRoot" Background="White">
    <ListBox ItemsSource="{local:CustomXMLExtension Source=Books.xml, Path=/Book/Title}" Height="200"
    Width="200" Background
    ="LightSalmon">
    </ListBox>
    </
    Grid>
    </
    Window>

The XAML markup shown here invokes the custom markup extension and passes the XML file name and path to bind to using the Source and Path attributes as shown below:

<ListBox ItemsSource="{local:CustomXMLExtension Source=Employee.xml,
Path=/Manager/FirstName}" Height="200" Width="200" Background="Beige" />

This makes declarative XML binding possible and as well as easier to work with.  And that's it! Now you' re ready to go. To build and execute, I mean.

The output of the above example will be as shown in Figure 1.

customWPF.bmp

Figure 1

In this manner, you can create any custom markup extension in WPF and use it in your applications.

Conclusion: In this article, you have learned how to create and use a custom markup extension.
 

Login to add your contents and source code to this article
share this article :
post comment
 

Useful Article

Posted by Dea Saddler Jul 08, 2011
Become a Sponsor
PREMIUM SPONSORS
  • Finally – a virtual platform that delivers next-generation Windows Server 2008 Hyper-V virtualization technology from a managed hosting partner you can truly depend on. Visit www.maximumasp.com/max for a FREE 30 day trial. Hurry offer ends soon. Climb aboard the MaxV platform and take advantage of High Availability, Intelligent Monitoring, Recurrent Backups, and Scalability – with no hassle or hidden fees. As a managed hosting partner focused solely on Microsoft technologies since 2000, MaximumASP is uniquely qualified to provide the superior support that our business is built on. Unparalleled expertise with Microsoft technologies lead to working directly with Microsoft as first to offer IIS 7 and SQL 2008 betas in a hosted environment; partnering in the Go Live Program for Hyper-V; and product co-launches built on WS 2008 with Hyper-V technology.
    ceTE software specializes in components for dynamic PDF generation and manipulation. The DynamicPDF™ product line allows you to dynamically generate PDF documents, merge PDF documents and new content to existing PDF documents from within your applications. Visit DynamicPDF here
Become a Sponsor