Plateforme Level Extreme
Abonnement
Profil corporatif
Produits & Services
Support
Légal
English
DependencyProperty ClearValue
Message
De
16/02/2009 05:23:11
 
 
À
15/02/2009 15:28:52
Information générale
Forum:
ASP.NET
Catégorie:
Windows Presentation Foundation (WPF)
Versions des environnements
Environment:
C# 3.0
Divers
Thread ID:
01381612
Message ID:
01382033
Vues:
49
>>>>>>Hi,
>>>>>>I've built a bool DependencyProperty (with the standard property wrapper) that implements inheritance.
>>>>>>If I set the property wrapper to 'true' I want it to set this on the DependencyProperty
>>>>>>But when I set it to 'false' I want to execute the .ClearValue() method instead.
>>>>>>I know I can't do this in the wrapper, or in the ValidateValueCallback - but can I do it in the CoerceValueCallback?
>>>>>>Or is there another way (maybe a wrapper for the wrapper?)
>>>>>>
>>>>>>Best,
>>>>>>Viv
>>>>>
>>>>>I've never actually used those functions... But so far in WPF when I can't do something like that from where I am, I can usually do it with a delegate.
>>>>>
>>>>>If that won't work, maybe you could post a little code that shows what you are trying to do.
>>>>Hi,
>>>>For now I've just used the wrapper to control this:
public class ShapeCanvas3: Canvas
>>>>       public static DependencyProperty ContentIsLockedProperty;
>>>>
>>>>        static ShapeCanvas3()
>>>>        {
>>>>            FrameworkPropertyMetadata p = new FrameworkPropertyMetadata();
>>>>            p.Inherits = true;
>>>>            ContentIsLockedProperty = DependencyProperty.Register("ContentIsLocked", typeof(bool), typeof(ShapeCanvas3), p);
>>>>        }
>>>>
>>>>        public bool ContentIsLocked
>>>>        {
>>>>            set
>>>>            {
>>>>                if (value)
>>>>                    SetValue(ContentIsLockedProperty, value);
>>>>                else
>>>>                    this.ClearValue(ContentIsLockedProperty);
>>>>            }
>>>>            get { return (bool)GetValue(ContentIsLockedProperty); }
>>>>        }
>>>>}
This works OK for me at the moment but ideally I'd like to prevent the DependencyProperty being set to false in XAML etc. I'll experiment with trying to do something in either the Valid or CoerceValue callback but, from the docs, it doesn't seem doable....
>>>>Regards,
>>>>Viv
>>>
>>>Ok... next silly question. Why do want to clear it?
>>>
>>>I think I'm not fully getting your code here, cause when I look at it, it looks like you are defaulting the value to true. So when you clear the control by setting it to false, wouldn't it still return true?
>>>
>>>I'm thinking you might have wanted to make it read only, but I'm not sure what you are trying to do.
>>
>>If true is passed in then it sets the property to true. When false is passed in I execute the ClearValue() so the value of the dependency property will be the inherited value. So the only two states the dependency property can have are either 'Locked' or the inherited state - it cannot be false (except via inheritance). The only flaw with this is that it is still possible to set the dependency property to false by methods other than via the wrapper property (for example by calling SetValue() directly). I was hoping to close these loopholes in one of the callbacks.
>>Regards,
>>Viv
>
>This was an interesting read:
>
>http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/9aca3e19-f9cd-47f4-89c2-39764f0b8274/

Hi,
Also explained well in the Apress WPF book and here: http://msdn.microsoft.com/en-us/library/ms745795.aspx

>
>Making it a readonly DP is one possible solution, it depends on where you need to be able to set it from. If it's all being set from codebehind I would think that would be the best solution.

Can't make it readonly because (a) I need to be able to set it to true and (b) I need inheritance.
IAC, if it's just being set in (my) code behind then there's no problem since I can always route through the wrapper.

>
>The problem with CoerceValueCallback is I don't see a way you get the default value there and it looks like calling ClearValue() from there would not be a good idea. My solution would be to add another property called CanUnlock, and test for that in CoerceValueCallback.

I think I CAN use a CoerceValueCallback to at least prevent it being set to false by:
private static object CoerceIsLocked(DependencyObject d, object value)
        {
            bool b = (bool)value;
            if (b)
                return b;
            else
                return DependencyProperty.UnsetValue;
        }
Main problem with that is that it could confuse other developers in that after
x.ContentIsLocked=true;
x.ContentIsLocked = false;
the property would actually be true with no indication that the expected value wasn't taken. The other alternative would be simply to return false from the validation callback if false is passed in (thus generating an exception). And the problem with that is that is is not instance specific so if a false value was ever acceptable in a specific case I would have no way of detecting it - whereas I could make the coerce value code conditional.....Arrrrrgggg

UPDATE: Two things:
(a) I found out that you need to use attached properties for inheritance (but this wasn't actually affecting the current situation)
(b) Using UnsetValue in the coerce callback is useless in this context. Unsetting just reverts the property to it's prior value - so a child element that was inheriting its property value from a parent ends up having that property explicitly set. Checking in the callback to see if the property is currently being explicitly set seems to work:
:
private static object CoerceIsLocked(DependencyObject d, object value)
        {
            if (d.ReadLocalValue(ContentIsLockedProperty) == DependencyProperty.UnsetValue)return value;
            bool b = (bool)value;
            if (b)
                return b;
            else
                return DependencyProperty.UnsetValue;
        }
Best,
Viv
Précédent
Suivant
Répondre
Fil
Voir

Click here to load this message in the networking platform