Windows Presentation Foundation · XAML

XAML Markup Extensions

Rob Relyea · · Restored archive post · Edited by Muhd Radhi Wahab
Restored from the windows-now.com archive. This post was originally published by Rob Relyea on 14 February 2006. It is reproduced faithfully for its historical and reference value, with the original author and date credited. If you are the author and would like this amended or removed, contact us.

Markup Extensions are documented in the Windows SDK here.

In addition to what that document says, you can also use Markup Extensions as elements.  Not just in attributes.

Somebody asked a question if you could have a tag map to an interface...the answer is no.  But you can have a tag map to a markup extension and do what ever you want in there.  This is a quick example of that.

I've built a sample MarkupExtension called ClassFactory and added it my small set of downloadable samples.

Here is a picture of this demo:

Editor's note: the original screenshot was hosted off-site and is not part of this restored archive.

 

XAML\MEasOE.xaml

...
    <Button>
      <RadioButton>test button</RadioButton>
    </Button>
    <Button>
      <Button.Content>
        <!-- Button.Content should not be necessary, but a bug requires it in this build-->
        <my:ClassFactory Type="RadioButton">
          <my:ClassFactory.Properties>
            <my:NameValuePair Name="Content" Value="Test button 2" />
          </my:ClassFactory.Properties>
        </my:ClassFactory>
      </Button.Content>
    </Button>
...

ClassFactory.cs

using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Serialization;
using System.Reflection;

namespace WpfDemos.XAML
{
    public class ClassFactory : MarkupExtension
    {
        public ClassFactory()
        {
        }
        private Type _Type;
        public Type Type
        {
            get { return _Type; }
            set { _Type = value; }
        }
        private List<NameValuePair> _Properties;
        public List<NameValuePair> Properties
        {
            get
            {
                if (_Properties == null)
                    _Properties = new List<NameValuePair>();
                return _Properties;
            }
        }

        //Provide value is called and the return value is used by
        //the XamlReader instead of the MarkupExtension.
        //This could be used to do additional work that normal XamlReading rules don't
        //support.
        public override object ProvideValue(object targetObject, object targetProperty)
        {
            object o =  Type.Assembly.CreateInstance(Type.FullName);
            foreach (NameValuePair prop in Properties)
            {
                PropertyInfo pi = Type.GetProperty(prop.Name);
                //This would need to add typeconverter support to set types that aren't
                //assignable by strings.
                pi.SetValue(o, prop.Value, null);
            }
            return o;
        }
    }
}

Frequently asked

Can you use a XAML markup extension as an element, not just in an attribute?

Yes. In addition to what the SDK documentation describes, you can also use Markup Extensions as elements, not just in attributes.

Can a XAML tag map to an interface?

No. But you can have a tag map to a markup extension and do whatever you want in there.