Open msedi opened 2 years ago
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label.
Tagging subscribers to this area: @safern See info in area-owners.md if you want to be subscribed.
@JeremyKuhne @RussKie @DustinCampbell for thoughts as this is tight to winforms designer.
Just to make sure, I took the behavior of the PropertyGrid as an example of what I'm thinking of: An object that mimics the access to a collection of objects of the same or of different types. I already have a running example that I can show and share here (but I'm not fully satisfied) which can be discussed.
I'm not quite sure I understand the ask here, e.g. why does MockObject
object need to be part of the .NET runtime (or Windows Forms for that matter) API, and how it would help.
If there is some extensibility endpoint is missing in ICustomTypeDescriptor
then we can certainly discuss this.
Couldn't you build your own dynamic object that accomplishes this? Why does it need to be in the runtime?
@davidfowl: Of course you are right, I could do it myself. I was just thinking if this is something that could be useful for others too. What do you think would be the right repository? Just in case: What would be the right repository, where to you keep System.ComponentModel for example or where would you put it?
@RussKie: Yes, the runtime is for sure the wrong place. I was just curious if this component would be something that could be useful for others too.
I think my only problem is (because I can build the rest myself), that there is no event on the ICustomTypeDescriptor that makes it "dynamic". So when you add or remove items from the MockObject that enforces the MockObjects to reevaluate its properties, attributes and events I cannot inform the outside to reevaluate. The same is true for the DynamicObject.
It can be seen again as an example in the PropertyGrid. If I attach a MockObject on the PropertyGrid as SelectedObject it gets is items evaluated and displayed. Once I add an item it does not get reevaluated automatically. I need to unassign (setting SelectedObject to null) and assign it again.
For the PropertyGrid this is not problem, because I can do it myself, but I don't know that something has changed.
I hope my explanation is somehow clear and understandable?
Background and motivation
When looking at the
PropertyGrid
(WinForms), you have the ability to set multiple objects of the same or of different types asSelectedObjects
. What the grid does internally is a union or an intersection of the properties and display the list of "surviving" properties in a list. It is of course depending on the implementation (telerik for example has a bit more features on it).Additionally the values of the properties are also shown. Thereby each property value is taken from each of the SelectedObjects' property value. If all values for each property value match, the value is displayed, if it doesn't match it is left empty.
While this is only a UI thing, many times I have the need to mimic this in code. For example, in my situation I have many windows displaying different content, with tools. There can be many tools on each display (e.g. drawing a circle). Then there is another window that groups all tools together (currently each tool group is a MockObject). This must be a dynamic behavior because tools can be added or removed, some displays support a tool, some not. What is necessary that if you want to activate a tool or if you want to modify properties of the tool (e.g. the circle color) you should need to walk through every display and set the properties for each and every tool (sometimes also this is neceessary). In almost 99% you want to select the properties for all displays, and this is where the MockObject come in.
Currently, if I have an object that I want to mimic I have to create a for loop for each property that distributes the values to all
SelectedObjects
. On the other side, I have to run through all of this when a value of a single object has been changed.My currently implementation look like this:
I have hidden the inner logic because its to long to be displayed here. This only work currently for the
PropertyGrid
because this one does the reflection by using theICustomTypeDescriptor
. There is one thing that doesn't work though - there is no way the PropertyGrid detects changes in the Objects, because there is obviously no way aICustomTypeDescriptor
can inform a listener that itsPropertyCollection
has changed (?) - as least I haven't found a way, so that anytime the PropertyCollection changes, one need to unassign and reassign the same object(s) to theSelectedObjects
. I assume this is a missing link to work better (dynamically) with thePropertyGrid
.One of the bigger problems with my solution is that it is not working in code, because the properties are only accessible and visible in the code editor when either using dynamic or when using reflection, writing directly into the
PropertyCollection
which is error prone since you only get runtime exceptions.API Proposal
API Usage
Risks
There are of course a few open questions: