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;
        #endregion

        #region Initialization

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

        }

        #endregion

        #region Properties

        public DataTemplate CustomeDataTemplate
        {
            get
            {
                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="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
                    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
                    xmlns:clr="clr-namespace:System;assembly=mscorlib" 
                    mc:Ignorable="d"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <DataTemplate x:Key="TestDataTemplate"
        DataType="{x:Type clr:Int32}">
    <Grid x:Name="PART" HorizontalAlignment="Left" VerticalAlignment="Top" DataContext="{Binding}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition MinWidth="154.98" Width="Auto"/>
            <ColumnDefinition Width="34.02"/>
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" MinHeight="50.96"/>
        </Grid.RowDefinitions>
        <StackPanel>
            <TextBox Margin="3" VerticalAlignment="Center" Text="TextBox" TextWrapping="Wrap"/>
            <Grid Margin="0" Height="103.84">
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="66.021"/>
                    <ColumnDefinition/>
                </Grid.ColumnDefinitions>
                <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>
                <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"/>
                </StackPanel>
            </Grid>
        </StackPanel>
        <ToggleButton Margin="3" VerticalAlignment="Top" Content="+" d:LayoutOverrides="Width" Grid.Column="1"/>
    </Grid>
    </DataTemplate>
</ResourceDictionary>

 

And a test class for example:

 

public class TestClass
        {
            [Browsable(true)]
            [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.