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
|
Hi, |
|
|
The MultipleObjectWrapper (or, rather, the Many<T> that it wraps around your properties) *should* be fanning out changes to all the properties that have been merged into the one that your DataTemplate is bound to. Your situation is obviously very complex and dynamic and it's hard to be sure why this isn't working for you or what would be required to fix it. Is it possible for you to provide us with a simple repro program so we can investigate the problem? To answer your question about why type editors and smart editors bind to different things: Your smart editor derives from ObjectWrappingEditor, which places an ObjectWrapper<T> around the property being edited. It does this so that the data template can two-way bind to primitive, immutable types (e.g. integers or strings) without needing to include the actual property name (so that you can reuse the same editor for different properties of the same type, e.g. Age and HatSize). TypeEditor, by contrast, does *not* (normally) place an ObjectWrapper<T> around the property, but instead provides the property value directly to the DataTemplate, so that its subproperties can be bound. The ObjectWrapper is not required because the template can two-way bind to subproperties by name (whereas it couldn't two-way bind to the value of an Int32). That is, a TypeEditor is inherently reusable for different properties of the same type, whereas a PropertyEditor or smart editor wouldn't be if it weren't for the object wrapping behaviour. Your smart editor could have TypeEditor-like behaviour by deriving from Editor instead of ObjectWrappingEditor: this would bypass the ObjectWrappingEditor's determination to wrap an ObjectWrapper<T> around every editee, but at the cost of having to do a bit more plumbing yourself. We can advise on this if it's what you want to do -- it should be pretty boilerplate. |
|
|
I've attached a cut-down repro project. To see the problem, build and run the project and: 1. Press the 'Entity 1' and 'Entity 2' buttons and notice they both have a property called 'String Prop' with a value of 'Foo'; 2. Press the 'Entity 1 and Entity 2' button (which will select them both) and notice that, correctly, the 'String Prop' property appears with the value 'Foo'; 3. Edit the property value from 'Foo' to, say, 'Bar'; 4. Press the 'Entity 1' and 'Entity 2' buttons again and notice that only one of them has changed to the new value (I found it was always Entity 1, which is the first Entity in the list given to the MultipleObjectWrapper when the 'Entity 1 and Entity 2' button is pressed).
Regarding the TypeEditor/SmartEditor binding issue, I am unconcerned with this at the moment.
Cheers |
|
|
Any update on this?
Cheers |
|
|
The issue appears to be that the PropertyString type is a reference type with value semantics. Thus, different instances of PropertyString report themselves to be equal, but they are not identical. Multiple selection support for subproperties (such as String Prop.PropertyValue) requires that equal String Prop references be identical. (And we should therefore be showing "inconsistent" for your PropertyStrings: it's misleading for us to show a value as though the objects were consistent.) I've looked to see whether we can improve this behaviour but it looks like this could involve significant changes to the grid, so I'm afraid we probably won't be able to do this quickly for you. In the meantime, I think what you'll need to do is bypass the built-in ManyEditor and craft your own editor templates which are aware of the fact that your values are not reference equal. This requires a couple of tricks: first, a TypeEditor to intercept the Many<PropertyString> values before the built-in ManyEditor gets them, and second, a control which knows how to fan out changes to the multiple PropertyStrings in the Many. The first is a simple TypeEditor declaration with one wrinkle: that XAML can't express the Many<PropertyString> type. So you need to create a markup extension for this: public class ManyOfExtension : MarkupExtension You can then write the TypeEditor as follows: <ms:TypeEditor EditedType="{mmor:ManyOf {x:Type mmor:PropertyString}}" The second can be easily, if a bit clunkily, implemented as a user control, with a single dependency property named MultiPropertyString of type Many<PropertyString> and a single text box as its UI. Here's the XAML for my simple control: <UserControl x:Class="Mindscape_ManyObjects_Repro.MultiPropertyStringEditor" Note I've resorted to using events rather than bindings: if you want to be MVVM-correct, you could create another property to serve as a binding source, but for purposes of the example I'm going to stick with the procedural version. Now for the user control code: public partial class MultiPropertyStringEditor : UserControl What's going on here? When the MultiPropertyString value is initialised, we check that the Many is consistent (which it will be if the PropertyStrings are equal), and if so initialise the TextBox with the PropertyValue (which will be plucked from the nominal Many.Value, which might be any of the PropertyString objects but it doesn't matter because they're all equal and therefore have the same PropertyValue). Now when the TextBox changes, we use the Many.Values property to get at all the underlying PropertyString instances, and set them to the new value. This is the missing piece that the built-in ManyEditor wasn't doing, because the built-in ManyEditor thought that there was only one PropertyString instance so it only needed to update that one. Note I haven't shown a particular UI for the inconsistent scenario -- you can use a trigger on MultiPropertyString.IsConsistent to display your desired UI in this case. Finally, our editor template hooks up the TypeEditor to the user control by setting the control's MultiPropertyString to the full Many<PropertyString> wrapper: <DataTemplate x:Key="mt"> Taken together, all this bypasses the ManyEditor and provides the behaviour you're looking for (at least in the simplified sample you provided). You'll probably need to take a look at how to make it more generic but hopefully this is enough to get you under way -- let us know if you need more info! |
|
|
That solution is working great for us :) Cheers! |
|