Question

PropertyGrid ExpandableCollectionConverter DisplayName

Posted 10 months ago by Avatar Neil Larson

The ExpandableCollectionConverter.ListItemPropertyDescriptor.DisplayName is based on property of the object (for example - MyGridDisplayName) in the collection, and I want to bind the ExpandableCollectionConverter.ListItemPropertyDescriptor.DisplayName to theMyGridDisplayName on the object, or somehow update DisplayName after the object is edited.

Lots of possible ways to go, but I'm hoping you can point me at the best way to do this.

Thanks, 

Neil


Comments (3)

Posted 10 months ago by Actipro Software Support - Cleveland, OH, USA

Hi Neil,

That can be a tad tricky, so please bear with me.  You effectively need to override the ExpandableCollectionConverter+ListItemPropertyDescriptor.DisplayName property, so you have to make a class that inherits ListItemPropertyDescriptor, then overrides the property with some appropriate value.

Next create a class that inherits ExpandableCollectionConverter and override the CreateListItemPropertyDescriptor method.  Have it return an instance of your MyListItemPropertyDescriptor class.

Finally use TypeConverterAttribute to put an instance of MyExpandableCollectionConverter on your collection property.  I think doing those steps will allow you to customize it.


Actipro Software Support
Posted 1 month ago by Neil Larson

This works for the initial creation of the list. 

I need to force the ExpandableCollectionConverter.ListItemPropertyDescriptor.DisplayName to be reevaluated when a property object changes. I did that by placing a propertychanged handler on all the items as they are added to the ListItemPropertyDescriptor. When I get the change event how do I make the ExpandableCollectionConverter redraw that one item?

 

      private class MyListPropertyDescriptor : ExpandableCollectionConverter.ListItemPropertyDescriptor
      {
         public MyListPropertyDescriptor(System.Collections.IList list, int index, Type itemType, Attribute[] attributes, bool isCollectionReadOnly, bool isReadOnly)
            : base(list, index, itemType, attributes, isCollectionReadOnly, isReadOnly)
         {
            // lay in a property change notification that will 
            var cmd = list[index] as MultiCueAddLogicalFireOrDwellCommand;
            if(cmd != null)
            {
               cmd.PropertyChanged += Cmd_PropertyChanged;
            }
         }

         private void Cmd_PropertyChanged(object sender, PropertyChangedEventArgs e)
         {
            // WHAT DO WE DO HERE???
         }

         public override string DisplayName
         {
            get
            {
               switch (this.List[Index])
               {
                  case MultiCueAddLogicalFireOrDwellCommand mcalcmd:
                     switch (mcalcmd.FiringType)
                     {
                        case MultiCueFiringType.None:
                        case MultiCueFiringType.Fire:
                           return $"T+{mcalcmd.TimingOffset:00.000} Id: {mcalcmd.LogicalId} Cue: {mcalcmd.Cue}";
                        case MultiCueFiringType.Dwell:
                           return $"T+{mcalcmd.TimingOffset:00.000} Id: {mcalcmd.LogicalId} Cue: {mcalcmd.Cue} Dwell {mcalcmd.Dwell:0.0}";
                        case MultiCueFiringType.DMX:
                           return $"T+{mcalcmd.TimingOffset:00.000} Id: {mcalcmd.LogicalId} Cue: {mcalcmd.Cue} DMX   {mcalcmd.Dwell:0.0}";
                     }
                     break;
               }
               return this.List[Index].GetType().ToString();
            }
         }
      }
Posted 1 month ago by Actipro Software Support - Cleveland, OH, USA

Hi Neil,

The IPropertyModel.DisplayName property gets bound directly to the TextBlock in each name cell's DataTemplate. So having your IPropertyModel raise an INotifyPropertyChanged.PropertyChanged event with "DisplayName" specified will update the UI. The TypeDescriptorFactory.GetPropertyModels method is where a PropertyDescriptorPropertyModel is created to wrap the PropertyDescriptor, and that in turn calls the virtual factory.CreatePropertyModel method.

Maybe you could override CreatePropertyModel and make a class inheriting PropertyDescriptorPropertyModel that knows how to attach to your MyListPropertyDescriptor. When it sees a MyListPropertyDescriptor passed in, it could create your PropertyDescriptorPropertyModel-based class and attach to an event so your PropertyDescriptorPropertyModel-based class could call its own NotifyPropertyChanged("DisplayName") method to let our UI know to refresh.


Actipro Software Support
Information The latest build of this product (2018.1 build 0673) was released 7 days ago, which was after the last post in this thread.

Add a Comment

Please log in to a validated account to post comments.