Jesse
Jesse

Reputation: 13

WPF Property Grid

Is there a way, when binding to a Dependency Object class, to hide class properties? I mean those "Dispatcher", "DependencyObjectType" and "IsSealed"?

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Windows;

namespace WPGDemoApp
{

   public class SampleObject : DependencyObject
   {
      readonly static DependencyProperty IdProperty = DependencyProperty.Register("ID", typeof(int), typeof(SampleObject));


      public int ID
      {
         get { return (int)GetValue(IdProperty); }
         set
         {
            SetValue(IdProperty, value);
         }
      }
      public string Name
      {
         get { return "Leeroy Jenkins"; }
      }
   }
}

Upvotes: 1

Views: 1779

Answers (2)

akjoshi
akjoshi

Reputation: 15772

Jesse, your question not very clear but if I understand it correctly you just want to show the properties present in your SampleObject i.e. those added by you and not the ones inherited from its base class.

1. check how your PropertyGrid is getting the properties of the selected object -

it should fetch the properties of selected objects type and not for object itself -

Type type = this.SelectedItem.GetType();

properties =TypeDescriptor.GetProperties(type);

instead of -

properties = TypeDescriptor.GetProperties(this.SelectedItem);

2. If this doesn't solve the problem or if you want more control over which properties to show in your PG then you can create a custom attribute. To achieve this I have created a custom attribute(similar to IsBrowsable), you just need to decorate your property with that attribute and modify your Property Grid implementation to honor it.

Here is the attribute class -

/// <summary>
/// Attribute to identify the Custom Proeprties.
/// Only Proeprties marked with this attribute(true) will be displayed in property grid.
/// </summary>
[global::System.AttributeUsage(AttributeTargets.Property, Inherited = true, AllowMultiple = false)]
public sealed class IsCustomPropertyAttribute : Attribute
{
    // See the attribute guidelines at 
    //  http://go.microsoft.com/fwlink/?LinkId=85236

    private bool isCustomProperty;

    public static readonly IsCustomPropertyAttribute Default = new IsCustomPropertyAttribute(false);
    public static readonly IsCustomPropertyAttribute No = new IsCustomPropertyAttribute(false);
    public static readonly IsCustomPropertyAttribute Yes = new IsCustomPropertyAttribute(true);

    /// <summary>
    /// Initializes a new instance of the <see cref="IsCustomPropertyAttribute"/> class.
    /// </summary>
    /// <param name="isCustomProperty">if set to <c>true</c> [is RT display property].</param>
    public IsCustomPropertyAttribute(bool isCustomProperty)
    {
        this.isCustomProperty = isCustomProperty;
    }

    /// <summary>
    /// Gets a value indicating whether this instance is RT display property.
    /// </summary>
    /// <value>
    ///     <c>true</c> if this instance is RT display property; otherwise, <c>false</c>.
    ///     The default is false.
    /// </value>
    public bool IsCustomProperty
    {
        get { return isCustomProperty; }
        set { isCustomProperty = value; }
    }

    /// <summary>
    /// Determines whether the specified <see cref="System.Object"/> is equal to this instance.
    /// </summary>
    /// <param name="obj">The <see cref="System.Object"/> to compare with this instance.</param>
    /// <returns>
    ///     <c>true</c> if the specified <see cref="System.Object"/> is equal to this instance; otherwise, <c>false</c>.
    /// </returns>
    public override bool Equals(object obj)
    {
        IsCustomPropertyAttribute attribute = obj as IsCustomPropertyAttribute;
        if (obj == null)
            return false;
        if (obj == this)
            return true;
        return attribute.isCustomProperty == isCustomProperty;
    }

    public override int GetHashCode()
    {
        return isCustomProperty.GetHashCode();
    }

    public override bool IsDefaultAttribute()
    {
        return isCustomProperty == IsCustomPropertyAttribute.Default.isCustomProperty;
    }
}

In your property grid, add a check before adding the property to grid. something like this -

// Gets the attributes for the property.
AttributeCollection attributes = propertyDescriptor.Attributes;

//Checks to see if the value of the IsCustomPropertyAttribute is Yes.
IsCustomPropertyAttribute myAttribute = 
(IsCustomPropertyAttribute)attributes[typeof(IsCustomPropertyAttribute)];

//Check if current property is CustomProperty or not
if (myAttribute.IsCustomProperty == true)
{
    AddProperty(propertyDescriptor);
}

Upvotes: 1

jwize
jwize

Reputation: 4165

This worked for expandable objects which were dependency objects. I just created a simple marker Attribute called ViewablePropertyAttribute. I didn't want all the dependency objects to be available in the grid.

    public class EllevateExpandableObjectConverter : ExpandableObjectConverter
{
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext   context, object value, Attribute[] attributes)
    {
        var propertyDescriptors =  
            base.GetProperties(context, value, attributes.OfType<ViewablePropertyAttribute>().Cast<Attribute>().ToArray());

        var result = propertyDescriptors.Cast<PropertyDescriptor>()
            .Where(pd => pd.Attributes.OfType<ViewablePropertyAttribute>().Any())
            .ToArray();

        return new PropertyDescriptorCollection(result);
    }
}

[ViewablePropertyAttribute]
[TypeConverter(typeof(EllevateExpandableObjectConverter)]
public MyComplexType MyInstance {get;set; }

Upvotes: 0

Related Questions