Search code examples
c#wpfpropertygridwpf-extended-toolkit

Wpf PropertyGrid Min/Max attrs


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!


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;
    }