FontEditor as WPGBrushEditor

Mar 28, 2011 at 11:11 AM

I have Font Property with FamilyName, FontSize, FontStyle and FontWeight.

How I can to show Property font as string "Arial,12" with sigh "+" in left part

and when I click on "+" to show his properties as subproperties?

Is it possible?

Mar 31, 2011 at 7:59 AM

Are you using System.Drawing.Font type?

Mar 31, 2011 at 10:04 AM
Edited Mar 31, 2011 at 10:04 AM

No, Silverlight don't have Drawing.

I have own Font class.

Mar 31, 2011 at 11:45 AM

I think i have some ideas... I'm not a guru in programming but may be my solution will help you.

At first property grid control need to know what DataTemplate must has property of your type. Adding a reference to the assembly in wich your type is declared is not a good practice. That's why i think dynamically loading the XAML will be a good idea. For that reason i added attribute class PropertyDataTemplate.cs that loaded resource dictionary where data template is declared:


    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public class PropertyDataTemplate : Attribute
        public Uri ResourceDictionaryUri { get; private set; }
        public string DataTemplateKey { get; private set; }
        public DataTemplate PropertyTemplate { get; private set; }

        public PropertyDataTemplate(string resourceDictionaryUri, string dataTemplateKey)
            this.ResourceDictionaryUri = new Uri(resourceDictionaryUri, UriKind.Relative);
            this.DataTemplateKey = dataTemplateKey;
            var template = ((ResourceDictionary)Application.LoadComponent(this.ResourceDictionaryUri))[dataTemplateKey];
            if (template != null)
                if (template is DataTemplate)
                    this.PropertyTemplate = template as DataTemplate;


Than in Property.cs added DataTemplate property of a property:


public class Property : Item, IDisposable
        #region Fields

        protected DataTemplate _template = null;

        #region Initialization

        public Property(object instance, PropertyDescriptor property)
            var propertyTemplateAttribute = this._property.Attributes.OfType<PropertyDataTemplate>().SingleOrDefault();
            if (propertyTemplateAttribute != null)
                this._template = propertyTemplateAttribute.PropertyTemplate;



        #region Properties

        public DataTemplate CustomeDataTemplate
                return this._template;

And in PropertyTemplateSelector.cs in "private DataTemplate FindDataTemplate(Property property, FrameworkElement element) {...}" method added 


private DataTemplate FindDataTemplate(Property property, FrameworkElement element)
            if (property.CustomeDataTemplate != null)
                return property.CustomeDataTemplate;
			Type propertyType = property.PropertyType;
			DataTemplate template = TryFindDataTemplate(element, propertyType);
            if (property.IsRequaredMaskInput)
                return TryFindDataTemplate(element, "maskedTextBox");
			while (template == null && propertyType.BaseType != null)
				propertyType = propertyType.BaseType;
				template = TryFindDataTemplate(element, propertyType);
			if (template == null)
				template = TryFindDataTemplate(element, "default");
			return template;


Also i created resource dictionary file - TestResourceTemplate.xaml where i put my data template:


<ResourceDictionary xmlns=""
    <DataTemplate x:Key="TestDataTemplate"
        DataType="{x:Type clr:Int32}">
    <Grid x:Name="PART" HorizontalAlignment="Left" VerticalAlignment="Top" DataContext="{Binding}">
            <ColumnDefinition MinWidth="154.98" Width="Auto"/>
            <ColumnDefinition Width="34.02"/>
            <RowDefinition Height="Auto" MinHeight="50.96"/>
            <TextBox Margin="3" VerticalAlignment="Center" Text="TextBox" TextWrapping="Wrap"/>
            <Grid Margin="0" Height="103.84">
                    <ColumnDefinition Width="66.021"/>
                <StackPanel Margin="0">
                    <Label Content="Family" Height="20" Margin="0,1" VerticalContentAlignment="Center" Padding="5,0"/>
                    <Label Content="Size" Height="20" Margin="0,1" VerticalContentAlignment="Center" Padding="5,0"/>
                    <Label Content="Style" Height="20" Margin="0,1" VerticalContentAlignment="Center" Padding="5,0"/>
                    <Label Content="Weight" Height="20" Margin="0,1" VerticalContentAlignment="Center" Padding="5,0"/>
                <StackPanel Margin="0" Grid.Column="1">
                    <ComboBox Margin="0,1" Height="20" Padding="4,0" VerticalContentAlignment="Center"/>
                    <TextBox Margin="0,1" Height="20" Padding="1,0" VerticalContentAlignment="Center" Text="{Binding Path=Value}"/>
                    <ComboBox Margin="0,1" Height="20" Padding="4,0" IsEnabled="False" VerticalContentAlignment="Center"/>
                    <TextBox Margin="0,1" Height="20" Padding="1,0" VerticalContentAlignment="Center"/>
        <ToggleButton Margin="3" VerticalAlignment="Top" Content="+" d:LayoutOverrides="Width" Grid.Column="1"/>


And a test class for example:


public class TestClass
            [WPG.PropertyDataTemplate("WPGDemoApp;component/TestResourceTemplate.xaml", "TestDataTemplate")]
            public int TestProperty { get; set; }
            public TestClass()
                this.TestProperty = 1000;
That's all, hope it'll help you. If you'll have some questions or a better way to realize it, please, let me know.

Mar 31, 2011 at 11:48 AM

My data template is just for testing... Just replace it with your own.