Introduction
I decided to write a little helper that saves control's template in an XAML file. I am a lazy person, so next time I need a template, I don't want to modify too much code. The class is easy to use, all what you need is to modify XAML of the control you are interested in. For example, you have some ThirdPartyControl
defined in XAML:
<ThirdPartyControl SomeProp="SomeValue"/>
Now, if you want to save the control's template in file template.xaml, just add the following attribute:
<ThirdPartyControl ExtractorNamespace:TemplateExtractor.FileName="template.xaml" SomeProp="SomeValue"/>
When your control loads, you'll have your template saved.
The Code
It's a class that contains attached property. On property assignment, it attaches onload
handler for the control which saves the template.
public class TemplateExtractor
{
public static readonly DependencyProperty FileNameProperty;
static TemplateExtractor()
{
var meta = new PropertyMetadata( null, OnFileNameChanged );
FileNameProperty = DependencyProperty.RegisterAttached
( "FileName", typeof( string ), typeof( TemplateExtractor ), meta );
}
private static void OnFileNameChanged( DependencyObject d, DependencyPropertyChangedEventArgs e )
{
var control = d as Control;
if( control == null ) return;
control.Loaded += OnControlLoaded;
}
private static void OnControlLoaded( object sender, RoutedEventArgs e )
{
var control = sender as Control;
if( control == null || control.Template == null ) return;
control.Loaded -= OnControlLoaded;
string fileName = GetFileName( control );
if( fileName == null ) return;
try
{
using( XmlWriter xmlWriter = XmlWriter.Create( fileName, new XmlWriterSettings { Indent = true } ) )
{
XamlWriter.Save( control.Template, xmlWriter );
}
}
catch { }
}
public static string GetFileName( FrameworkElement frameworkElement )
{
return (string)frameworkElement.GetValue( FileNameProperty );
}
public static void SetFileName( FrameworkElement frameworkElement, string value )
{
frameworkElement.SetValue( FileNameProperty, value );
}
}