This thread looks to be a little on the old side and therefore may no longer be relevant. Please see if there is a newer thread on the subject and ensure you're using the most recent build of any software if your question regards a particular product.
This thread has been locked and is no longer accepting new posts, if you have a question regarding this topic please email us at support@mindscape.co.nz
|
We like the PropertyGrid so much we want to use it for everything. We have one situation that’s causing us to scratch our heads. It occurred to us you may already have come across it before and could provide some guidance on how to resolve it. One of the properties on several of our objects is actually a reference to another object. We want to also display the properties of the object that is referenced by the value of the property shown in the grid. To illustrate the issue, I’ve attached a sample app that mimics the structure and properties of our code. The sample displays a list of vehicles of various types that will be put up for sale. When the user selects a sale vehicle, the PropertyGrid displays a combobox containing a filtered list of vehicles matching that type from the list of vehicles in stock. Unfortunately, only the VehicleId can be displayed (the underlying collection actually only knows the IDs), so the user can’t find out anything more about the vehicle in stock – e.g., it’s make, model, or color. I’d like the PropertyGrid to display (and allow editing of) the properties of the referenced stock vehicle. So when the user selects an ID from the combobox, the PropertyGrid would be able to locate the item from the list of available stock vehicles and should dynamically display the make, model, and color for editing right there at the same time. Ideally, there would be a way to create a new stock vehicle of the appropriate type right in the PropertyGrid and allow the user to modify the properties of it. Granted it’s a simplification, so sometimes the metaphor doesn’t’ make real-world sense, but hopefully it will be helpful to understand the problem. Note that I am currently using a custom PropertyEditor (derived from ObjectWrappingEditor) for the VINPropertyEditor. The DataTemplate used for the property had to be built in code. This was necessary to ensure a new instance of the filtered CollectionViewSource of available stock vehicles was created for each instance of a vehicle for sale. With a shared instance of the CollectionViewSource, applying a new filter resulted in the previously set property values for a different type of vehicle being wiped out. The source list of available stock vehicles is passed in as the PropertyGrid’s EditContext. (This works well, but has the drawback that I cannot add a SelectedItemChanged event handler function for the combobox that would reside in my VINPropertyEditor class (which is not a window) or in the MainWindow class.) Have you run into this kind of a request before – to display properties of an object that is referenced by a property of the selected object in the PropertyGrid? How can this be accomplished? And how can we provide a mechanism for the user to create a new object of the referenced type and set its properties – all from the PropertyGrid? |
|
|
Hello BillBR This is an interesting scenario which I have not come across before. The only solution I've come up with is to add the nodes dynamically to the PropertyGrid. You can use the PropertyGrid.AddNode method to add custom nodes. You could add one node for each property of the Vehicle that was selected by the user. Jason Fauchelle |
|
|
Thanks for reply, Jason. FYI, I was able to add a handler for the SelectionChanged event of the ComboBox in the DataTemplate I'm creating in code. The FrameworkElementFactory has a method for hooking that up:
The ComboBox_SelectionChanged handler, added to the custom PropertyEditor, is called whenever the user changes the selection. Regarding the suggestion to add custom nodes for the properties of the Vehicle selected by the user, that would be an interesting approach. But how would you accomplish it? AddNode is a member of PropertyGrid, but there are no methods or properties for reaching the parent PropertyGrid object from either a contained node or custom PropertyEditor (where the change in the combobox's selection (which would trigger the adding of the nodes) can be detected. Since you can't get to the PropertyGrid from within the custom PropertyEditor, you can't add nodes to it. Did you know of some particular way to do this? |
|
|
Hello BillBR I would do it by listening to when the property changes on the model rather than the ComboBox. When the model is set to be the SelectedObject of the PropertyGrid, attach an event handler to listen to when the appropriate property change on that model. (The one that holds the selected value of the combo box). When this changes, add the custom nodes to the PropertyGrid as necessary. This logic can be encapsulated in a class that controls the PropertyGrid based on the SelectedObject. Also when the SelectedObject changes, you'd want to remove the event handler from the previous object, and attach one to the new object. Jason Fauchelle |
|
|
Thanks for the direction on this, Jason. I like that it focuses on the change to the actual property rather than to the selected item in the ComboBox. This approach may work for some, but for us it did not. To detect changes to the property that is a reference (VIN in my sample code) requires modifying the various classes (PickupTruck, Car, and Van) to support INotifyPropertyChanged so the PropertyChanged event is raised on the property when the user selects an ID from the ComboBox. In our real app, for various reasons, that's not an option. However, I was able to resolve this issue a different way. I added a second PropertyGrid to the DataTemplate of the custom property editor. So I have the exterior PropertyGrid displaying a node with a custom property editor that contains an interior PropertyGrid for editing the referenced object's properties. It works well and the user experience is quite seamless. I've adapted my original sample code to demonstrate how this works. The new version (attached) adds more properties to the Vehicle class and includes a list of the available stock vehicles at the top of the main window so you can observe the changes made to their properties during editing. When the user selects a Vehicle for Sale, the exterior PropertyGrid displays the VIN in the custom property editor's ComboBox. Since initially the VIN is null and no item is initially selected, the interior PropertyGrid displays nothing. When the user selects one of the of the stock vehicles from the dropdown, the VIN is set and the interior PropertyGrid displays the properties of the referenced stock vehicle. Editing these properties causes changes to the Vehicle's properties as visible in the ListBox. The custom property editor, VINPropertyEditor, now in its own class file, has a new property, "Data", that raises the PropertyChanged event when set. CreateDataTemplate() now creates a DataTemplate consisting of a grid with two rows, one for the ComboBox and another for the PropertyGrid, whose SelectedObject property is bound to the new Data property. A new SelectionChanged event handler for the ComboBox uses the selected VehicleId to set the Data property to that particular stock vehicle from the list. The change in the Data property triggers the interior PropertyGrid to display the properties of the referenced stock Vehicle object. My example was simple and had no properties with complex types or collections. As such, I did not need to use the new ExpanderNode property of the PropertyGrid (in your nightly builds as of July 30, 2013) to cause all nodes to be initially displayed as 'expanded'. However, if someone modifying the sample code for their own project would like that user experience, it can be accomplished by adding a using statement for Mindscape.WpfElements.WpfPropertyGrid and the following code to the CreateDataTemplate function at line 152:
Thanks for providing that new capability to the PropertyGrid! As always, thanks for your assistance working through issues and your prompt attention to your customers, BillBR |
|
|
Hello BillBR Great to see you found a solution, this works very well. Thanks for posting the implementation and description. Jason Fauchelle |
|