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
|
Short Summary: When binding to a Property using a Converter, a PropertyChanged event on the Property does not refresh the binding. Long Story: I have a minor confusion. I'm trying to create datatemplates for properties of a fairly complex legacy type (I'll call it IMyLegacyThingy). It's effectively a heavily overlapping flag enum value, so I'm rolling my own checkbox item combobox for it. At a basic level, that's working fine. However I also need to display a string "summary" of the flags which are set. For various reasons the best way for me to do this seems to be with the following sort of datatemplate (nb: vastly simplified down, the real one also binds a mess of other things: <DataTemplate x:Key="EnumFlagValueTemplate"> Now, MyConverter takes the Property, and a parameter, and being smart is able to return all sorts of useful stuff from the dark and scary gizzard of IMyLegacyThingy. Unfortunately the Value of the node is insufficient for me to get enough information. class MyConverter : IValueConverter } The problem is that when the property's notifychanged event happens, the binding above is not refreshed/retriggered. If I change it to: <TextBlock Text="{Binding Path=Value, Mode=OneWay, Converter={StaticResource MyConverter}, ConverterParameter=Value, UpdateSourceTrigger=PropertyChanged}" /> Then the notifychanged *does* trigger a refresh.Now I'm not sure, but I expected that refreshing a property's value woudl trigger a refresh of the Node. Perhaps Node just needs to implement INotifyPropertyChanged? Otherwise, Is there any way you can think of for me to get my custom converter to refresh itself when the Node's Value changes? Anything else I can bind to, or flag I can set on my binding which achieves my goals? |
|
|
The reason Node doesn't notify of changes is that Node basically packages up two things: the data source (which remains the same object even when one of its property values changes) and the property metadata (which remains the same even when the value changes). Yes, Node also happens to wrap up the logic for invoking the property getter against the data source, but that's really a convenience. (And maybe we should have made it a GetCurrentValue method rather than a Value property, so as to be more explicit about this, or made it internal or something.) A Node's basic job is to represent, well, a node in the grid -- a slot, if you like -- and the slot doesn't change. So much for philosophy. As to your problem, I don't think I've understood it fully. You say that binding to Value rather than to Property does trigger a refresh. So why not do that? Binding to Value is the normal idiom for property editors. Is there something you need from Property that Value doesn't give you (e.g. the metadata)? Or is it that Value is one of the subproperties of the IMyLegacyThingy rather than the IMyLegacyThingy itself? I am also a bit unsure of whether your template is associated with an IMyLegacyThingy property of the main object, or a property of an IMyLegacyThingy. Sorry if these are dumb questions...! |
|
|
[quote user="ivan"] Is there something you need from Property that Value doesn't give you (e.g. the metadata)? Or is it that Value is one of the subproperties of the IMyLegacyThingy rather than the IMyLegacyThingy itself? [/quote] I apologise for the going into too much detail here, but in short - yes, there is information I need from the Node. The data template is being used to present a single property of type IMyLegacyThingy which is a dynamically generated (the underlying object implements ICustomTypeDescriptor). Due to some evil (did I say Legacy code?), by the time Mindscape gets it's hands on the value, it thinks that Property.Value is of type String. It's not really, but the underlying implementation of MyLegacyThingy is: public IMyLegacyThingy { /*blah*/ } public IMyLegacyField { /* blah */ } internal MyLegacyField<T> : PropertyDescriptor, IMyLegacyField So Mindscape assumes that the value *is* a string. Which it kinda is, but not really. That behaviour is ok (and required by my legacy code) for simple back and forward assignment translations of values, but I need the actual underlying implementation type in order to get my own meta information about the property. I need this to provide a rich control here for my users, and do so by using Property.Name and Property.Source (as well as Property.IndexedPropertyArguments) in order to get and set the *real* type, values and metainformation of the property (you can see me casting Node.Source to my known type in the first post above). And that's all fine except that when the property changes, nothing in my grid thinks it's worth refreshing. I guess I should try making my converter a multibindingconverter and bind both Value and Property even though I don't really need or want Value. I'll see how that goes. |
|
|
Wow, that's a pretty complex scenario. I too would go with the MultiBinding using Value to do the triggering. It does feel a bit ugly but pragmatically it should get the job done (it's a compromise I've made myself on several occasions *grin*). The purist approach would probably be to create some sort of ViewModel class that could wrap everything that was required and present a more binding-friendly API, but depending on your use case that may well be more trouble than you want to go to -- and can potentially introduce problems of its own... |
|
|
[quote user="ivan"]The purist approach would probably be to create some sort of ViewModel class that could wrap everything that was required and present a more binding-friendly API, but depending on your use case that may well be more trouble than you want to go to -- and can potentially introduce problems of its own...[/quote] Indeed. The complexity of what I've described above is dwarfed only by the actual complexity of the viewmodel I'd need to write. To confirm, once the binding includes the Value dependencyobject everything works just spiffily (even though my multivalueconverter ignores that parameter completely and just oncalls my original valueconverter). Thanks for your feedback again. Hopefully this post has enough keywords to lead someone else to a similar fix one day. |
|