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
|
Hello, I have a business object that contains an 'Effective Date' property. I want to be able to: a) Edit this value if the effective date is GE than Today b) Make this a read only value if the date LT than Today The other properties of the business object have no such conditional logic. How can I do this? Regards, Douglas Birch |
|
|
Have a look at http://www.mindscape.co.nz/blog/index.php/2008/07/15/choosing-wpf-property-grid-editors-from-code/ -- in this case the DataTemplateSelector solution is probably the most appropriate. (Because selectors run only once, this does mean that if the effective date is GE than today when the property is first displayed, but the object remains selected for hours or days so that the the effective date is now in the past, the property will still appear editable. I'm hoping this won't be an issue!) |
|
|
Thank you for the link ... that (using the XAML approach) worked real well. |
|
|
Hello, I'm enjoying the conditional editing capabilities of the properties grid. So, one <last> question on this ... I have a 'Yes/No' field ... When the user changes the field value from 'No' to 'Yes' ... I want to change a couple read only fields to editable fields ... likewise when the user changes the field value from 'Yes' to 'No' ... I want to make the same two fields read only ... So, what I'm stuck on is, how I re-trigger my property editor data template selectors when my Yes/No field toggles in value ... how can I do this? Regards, Douglas |
|
|
You can't re-run a DataTemplateSelector on demand. So if you need to change an editor template not just based on a once-only criterion (like the date) but as the data itself changes, you can't use the selector-based approach. Instead you will need to use a trigger. Triggers respond to runtime events and therefore allow the template to change even after it's been instantiated. See http://www.mindscape.co.nz/blog/index.php/2008/03/24/triggers-and-selectors-in-wpf-templating/ for a quick introduction to triggers and selectors. How would this work in the situation you describe? It depends on how significant the change is from editable to read-only. For example, if your editor template is just a TextBox, all you need to do is set up a trigger to flip the IsReadOnly property: <DataTemplate> (Apologies for any syntax errors -- I'm typing this directly into the forums.) Hopefully you can see what's going on here: the trigger monitors the is-editable-expression. (We'll come back to what the is-editable-expression actually is in a moment.) If that ever evaluates to False, it applies the Setter, which sets the IsReadOnly property of the TextBox to True. If the is-editable-expression stops evaluating to False, it stops applying the Setter, so the IsReadOnly property of the TextBox returns to its default value (False). Sometimes your change from editable to read-only will be a bit more dramatic. For example, an editable DateTime might use the date editor, while a read-only one might use a TextBlock with suitable formatting. In this case, the principle remains the same, but the template gets a bit more complicated: probably you'll have two controls, maybe superimposed on each other using a Grid, and use the trigger to show the appropriate one and hide the other. Here's a (somewhat simplified) example: <DataTemplate> A couple of things to notice in both cases: 1. You don't need to explicitly provide handling for the "when it changes back" case: WPF will take care of applying the setters only for as long as the trigger remains in force, and removing them when it ceases. 2. For triggers to work your data object
MUST raise property change notifications (via INotifyPropertyChanged).
WPF relies on this to detect when the trigger expression changes so
it can re-evaluate the trigger. Okay, what about the mysterious is-editable-expression? This wants to refer to one of the other properties on the edited object, but how do we get to that property? The answer is that, in addition to the usual Value, property editors have access to some other information, which you can find in the ObjectWrapper class. The UnderlyingObject gives us access to the object whose property we are editing. So if editability of the property at hand is determined by the IsFooEditable property of the object, our is-editable-expression is "{Binding UnderlyingObject.IsFooEditable}". I've tacitly assumed in the above examples that the is-editable-expression is boolean; of course a trigger can use any data type. So for example if your IsFooEditable property is a string then your trigger can be <DataTrigger Binding="{Binding UnderlyingObject.IsFooEditable}" Value="No">. And you can use value converters in the binding, or use a MultiBinding or MultiDataTrigger if you need to consider multiple properties in making the editable/read-only decision. See also the forums thread at http://www.mindscape.co.nz/forums/Thread.aspx?PostID=2289. |
|
|
Hello, Thank you for the thorough explanation ... much appreciated! I put it to use and it works quite well. Here is how I used it .. first the data template: < DataTemplate x:Key="MinOccurDataTemplate"> <Grid> <ms:NumericUpDown Name="MinOccurEditable" Value="{Binding Value}" Minimum="0" Maximum="99" Visibility="Visible" /> <TextBlock Name="MinOccurReadonly" Text="{Binding Value}" Visibility="Collapsed" /> </Grid> <DataTemplate.Triggers> <DataTrigger Binding="{Binding UnderlyingObject.IsMultiOccurrence}" Value="N"> <Setter TargetName="MinOccurEditable" Property="Visibility" Value="Collapsed" /> <Setter TargetName="MinOccurReadonly" Property="Visibility" Value="Visible" /> </DataTrigger> </DataTemplate.Triggers> </DataTemplate>Then I added the property editor to reference it: < ms:PropertyEditor PropertyName="MinimumOccurrences" EditorTemplate="{StaticResource MinOccurDataTemplate}" />Thanks again. Regards, Douglas |
|