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:
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;
}
}
}