Question

I am using PropertyGrid from WPF Extended toolkit for a lot types of objects. Objects are wrapps for configs. Many properties are integers and I want to define minimum/maximum range of concrete property in the class definition.

Something like this:

    [Category("Basic")]
    [Range(1, 10)]
    [DisplayName("Number of outputs")]
    public int NumberOfOutputs
    {
        get { return _numberOfOutputs; }
        set 
        {
            _numberOfOutputs = value;
        }
    }

Is there some solution to achive that? I think it is possible with PropertyGrid custom editor, but I mean it is unnecessarily complicated.

Thank you very much!

Was it helpful?

Solution

You can achieve this by extending PropertyGrid code.

Following code working with integer properties.

Step by step:

1) Download source Extended WPF Toolkit from https://wpftoolkit.codeplex.com/SourceControl/latest.

2) Add Xceed.Wpf.Toolkit project to your solution.

3) Add RangeAttribute class in the following namespace:

namespace Xceed.Wpf.Toolkit.PropertyGrid.Implementation.Attributes
{
    [AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
    public class RangeAttribute : Attribute
    {
        public RangeAttribute(int min, int max)
        {
            Min = min;
            Max = max;
        }

        public int Min { get; private set; }
        public int Max { get; private set; }
    }
}

4) Edit code in class ObjectContainerHelperBase to assign Min and Max values to appriopriate editor (IntegerUpDown). I posted entire method GenerateChildrenEditorElement, just replace this method with following code:

private FrameworkElement GenerateChildrenEditorElement( PropertyItem propertyItem )
{
  FrameworkElement editorElement = null;
  DescriptorPropertyDefinitionBase pd = propertyItem.DescriptorDefinition;
  object definitionKey = null;
  Type definitionKeyAsType = definitionKey as Type;

  ITypeEditor editor = pd.CreateAttributeEditor();
  if( editor != null )
    editorElement = editor.ResolveEditor( propertyItem );


  if( editorElement == null && definitionKey == null )
    editorElement = this.GenerateCustomEditingElement( propertyItem.PropertyDescriptor.Name, propertyItem );

  if( editorElement == null && definitionKeyAsType == null )
    editorElement = this.GenerateCustomEditingElement( propertyItem.PropertyType, propertyItem );

  if( editorElement == null )
  {
    if( pd.IsReadOnly )
      editor = new TextBlockEditor();

    // Fallback: Use a default type editor.
    if( editor == null )
    {
      editor = ( definitionKeyAsType != null )
      ? PropertyGridUtilities.CreateDefaultEditor( definitionKeyAsType, null )
      : pd.CreateDefaultEditor();         
    }

    Debug.Assert( editor != null );

    editorElement = editor.ResolveEditor( propertyItem );

      if(editorElement is IntegerUpDown)
      {
          var rangeAttribute = PropertyGridUtilities.GetAttribute<RangeAttribute>(propertyItem.DescriptorDefinition.PropertyDescriptor);
          if (rangeAttribute != null)
          {
              IntegerUpDown integerEditor = editorElement as IntegerUpDown;
              integerEditor.Minimum = rangeAttribute.Min;
              integerEditor.Maximum = rangeAttribute.Max;
          }
      }
  }

  return editorElement;
}

OTHER TIPS

Just found myself needing something similar, for setting the visibility value (only double type from 0.0 to 1.0 should be allowed).

But I went with a different solution, so here it is in case it helps someone:

[Category("Visibility")]
[DisplayName("Visibility value")]
[ItemsSource(typeof(MyVisibilityItemsSource))]
public double MyVisibility { get; set; }
public class MyVisibilityItemsSource: IItemsSource
{
    public ItemCollection GetValues()
    {
        ItemCollection visibilities = new ItemCollection
        {
            0.0,
            0.1,
            0.2,
            0.3,
            0.4,
            0.5,
            0.6,
            0.7,
            0.8,
            0.9,
            1.0
        };
        return visibilities;
    }
}

This will display a ComboBox with the numbers from the ItemCollection above. It's not ideal when there is a lot of numbers in the range, but it gets the job done for something simple like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top