Category name translation

Grids for WPF Forum

Posted 2 years ago by Procam
Version: 18.1.1
Avatar

There is a way how to deal with the text of Category name using CategoryEditor? For example, for property name I use this PropeertyEditor:

<grids:PropertyEditor>
	<grids:PropertyEditor.NameTemplate>
		<DataTemplate>
			<TextBlock  x:Name="txtProperty"  Margin="4,0,0,0" HorizontalAlignment="Stretch" VerticalAlignment="Center">
				<TextBlock.Text >
					<MultiBinding Converter="{StaticResource TranslationConverter}">
						<Binding ElementName="txtProperty" Path="."></Binding>
						<Binding Path="DisplayName"/>
					</MultiBinding>
				</TextBlock.Text>
			</TextBlock>
		</DataTemplate>
	</grids:PropertyEditor.NameTemplate>
</grids:PropertyEditor>

so, that way I am able to translate the property name by means of my converter

There is some way how, in a similar way to the code above, to deal with the category name text?

Comments (12)

Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

If you mean you wish to localize the text for the category name that is displayed above properties when properties are categorized in the PropertyGrid, you would have two options...

1) Clone and update the default Style we set to the PropertyGrid.DefaultCategoryItemContainerStyle property.  The Style we set there has a Template set that is where the TextBlock is.  This would require you to have our default styles/templates.

or

2) If you use the DisplayAttribute on your properties instead of DisplayNameProperty/CategoryAttribute, you can localize the string values using .NET string resources.  That overall might be an easier way to go since DisplayAttribute is made for string localization.


Actipro Software Support

Posted 2 years ago by Procam
Avatar

Hello,

regarding the 2. point, in some of the properties we use the three attributes (Category, DisplayName, and Display attribute), e.g.:

[Category("Graphic"), DisplayName("Color"), Display(Order = 3), SetModified]
        public virtual Color LineColor

but I do not understand how can I deal with the Category name, as you advised, using the Display attribute instead of the DisplaName/Category attribute? The DisplayName attribute we use for dealing with the property name, as shown in our xaml code above.

Regarding the 1. point, do you have some sample code? I can not find any in the sample app.

Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

Yes the link for DisplayAttribute in the previous reply points to our documentation (see below) on using that attribute and an example.  The one attribute can replace the use of the others.

From Documentation

This code shows an example of applying DisplayAttribute to set sort order (via Order), category (via GroupName), display name (via ShortName), and description (via Description) for a property:

public class Foo {
	[Display(Order = 4, GroupName = "Common", ShortName = "Bar Property", Description = "A description about Bar.")]
	public int Bar { get; set; }
}


Actipro Software Support

Posted 2 years ago by Procam
Avatar

Hello,

for the localization, we do not use such an approach with .NET string resources.

Instead of that, our XAML uses a converter with such code:

BindingOperations.SetBinding(textBlock, TextBlock.TextProperty, new Binding("Value") { Source = new TranslationData(resultText, null) });

It means the Dependency property (e.g. Text) of the Dependency object (e.g. TextBlock) is bound to the property 'Value' of object TranslationData (that implements INotifyPropertyChanged). When the language is changed, the PropertyChanged event of this property is invoked returning the desired translation from our excel file (repository of all translations, all languages).

Taking this into count, it seems I have to apply your clone/update proposal. Does it mean I have to re-template the whole Grids.xaml? Do you have some sample for me?

Anyways, it should be nice, as for PropertyEditor, to provide something similar also for CategoryEditor, something like this:

<grids:CategoryEditor>
	<grids:CategoryEditor.NameTemplate>
		<DataTemplate>
...
		</DataTemplate>
	</grids:Category.NameTemplate>
</grids:CategoryEditor>

Thanks for you reply.

Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hello,

You wouldn't have to clone all of the Grids XAML, just the PropertyGrid.DefaultCategoryItemContainerStyle default value, which is just 30-something lines long.

A third option is that you could override the TypeDescriptorFactory class with a MyTypeDescriptorFactory class of your own.  Then override its CreateCategoryModel method, which is passed the category name and you return a CategoryModel from it.  Here's the default logic:

protected virtual ICategoryModel CreateCategoryModel(string name, IDataFactoryRequest request) {
	return new CategoryModel(name);
}

You could apply your translation there instead.  Then set an instance of your custom MyTypeDescriptorFactory class to the PropertyGrid.DataFactory property.


Actipro Software Support

Posted 2 years ago by Procam
Avatar

Well, I can clone the 42 lines of code. But then the PropertyGridCategoryItemContainerStyle is based on PropertyGridItemBaseContainerStyle, and this is based on another, and so on, as you can see in the code snippets:

<grids:PropertyGrid x:Class="Procam.Gdm.Controls.UserControls.CustomPropertyGrid"
   ...   
   DefaultCategoryItemContainerStyle="{StaticResource PropertyGridCategoryItemContainerStyle}">

and as this CustomPropertyGrid is used in more parts of the app, so I put the style in the App.xaml:

<Style x:Key="PropertyGridCategoryItemContainerStyle" TargetType="grids:PropertyGridItem" BasedOn="{StaticResource PropertyGridItemBaseContainerStyle}">
   ...
</Style

In my code I omitted the BasedOn="{StaticResource PropertyGridItemBaseContainerStyle}" and it seems to work but I am not sure if I can freely omit this base style(s)? It is not possible to track all the stuff contained in these base styles.

Answer - Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

I think you can get away with leaving the BasedOn out in this case.  The default Style for PropertyGridItem is based on PropertyGridPropertyItemContainerStyle, which is based on PropertyGridItemBaseContainerStyle.  Therefore, I think you can probably make your custom PropertyGridCategoryItemContainerStyle and not base it on anything and it should pull what it needs from the default PropertyGridItem Style that has all the PropertyGridItemBaseContainerStyle Setters already in it.


Actipro Software Support

Posted 2 years ago by Olivier
Avatar

Hi Friends,

I have quite a similar case, I want the grid category item DisplayName to be bindable.

I've already done that for property item, thanks to PropertyModel that has bindable properties (namely PropertyModel.DisplayNameProperty).

But for categories, there is not such thing ...

Can you give me some hints on how to do that ?

(I've tried to change grid's category style, and to override CreateCategoryModel without luck).

Thanks !

Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Olivier,

Can you clarify what's not working?  The Style currently set in PropertyGrid.DefaultCategoryItemContainerStyle has a Template that does bind its TextBlock.Text value to the CategoryModel.DisplayName property.  Any changes to DIsplayName should reflect in the UI.


Actipro Software Support

Posted 2 years ago by Olivier
Avatar

Yes indeed, TextBox.Text is bound to CategoryModel.DisplayName in template.

But the thing is that CategoryModel.DisplayName is a simple property, not a DependencyProperty, and thus I cannot bind it to anything.

This is a little bit tricky, because CategoryModel.DisplayName should reflect PropertyModel.CategoryProperty of its child items.

So in theory, one should not be able to set directly CategoryModel.DisplayName.

To clarify, I'm in a situation where all grid texts (property name + category name) are localized.

So I'm using PropertyModel to bind CategoryProperty & DisplayNameProperty to my translator instance.

When the current langage changes, both properties are actually changed, and I can see the property name changing "on the fly".

But this is not the case for category name, even if items category has changed ...

Posted 2 years ago by Olivier
Avatar

I've managed to make it work.

Many problems to overcome :

- override CreateCategoryModel to use homemade class

- monitor Category's children Category property to update Category.DisplayName

- override CreateMyPropertyModel to use homemade class

- override PropertyModel.Category to use another one, because default one do not trigger PropertyChanged ...

- others under the hood tricks

But thanks to this, I can update Category.DisplayName on the fly.

Moreover, because I use PropertyModel to bind item's Visibility, I can now auto hide/show Categories based on their children visibility.

Posted 2 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar

Hi Olivier,

I'm glad you got it working.

FYI, the PropertyModel class is only bindable because it's a specialized class that is intended to be used directly in XAML in certain circumstances. 

Whereas if you use the more normal PropertyGrid.DataObject way of adding properties, those come through a POCO (plain old CLR object) PropertyDescriptorPropertyModel class that doesn't inherit DependencyObject.  Likewise, CategoryModel doesn't inherit DependencyObject.

As you saw, PropertyGrid is very extensible and you don't have to use our POCO CategoryModel class.  You create instances of custom classes in methods like factory.CreateCategoryModel and inject any specialized functionality you need that way.


Actipro Software Support

The latest build of this product (v24.1.1) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.