4

I have the following declaration:

public static readonly DependencyProperty PassColorProperty = DependencyProperty.RegisterAttached("PassColor",
            typeof(string),
            typeof(ColorMasking),
            new PropertyMetadata("#FFCCFF"));

    public string PassColor
    {
        get { return (string)GetValue(PassColorProperty); }
        set { SetValue(PassColorProperty, value); }
    }

At the moment this code does not compile because I haven't added : DependencyProperty to my class. When I add that code it says that the string PassColor is invalid.

Without the string there at all, the code compiles and I can set read the property from within that class. I cannot set it from my XAML though. It says the property doesn't exist. My xaml is:

<TextBox Grid.Column="1" Grid.Row="8" Margin="3" Width="Auto" Height="Auto" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" 
                b:ColorMasking.Mask=" ... Long Regex Command ... "
                b:ColorMasking.PassColor="99FF99" />

The code for setting the Mask works perfectly. I think I have copied all the required stuff too. It is confusing as to why I cannot add another property.

If it matters, this is a variation I've written of this code: How to define TextBox input restrictions?

EDIT:

public class ColorMasking : DependencyObject
{
    private static readonly DependencyPropertyKey _maskExpressionPropertyKey = DependencyProperty.RegisterAttachedReadOnly("MaskExpression",
            typeof(Regex),
            typeof(ColorMasking),
            new FrameworkPropertyMetadata());

    /// <summary>
    /// Identifies the <see cref="Mask"/> dependency property.
    /// </summary>
    /// 
    public static readonly DependencyProperty PassColorProperty = DependencyProperty.Register("PassColor",
            typeof(string),
            typeof(ColorMasking),
            new PropertyMetadata("#99FF99"));

    public static readonly DependencyProperty FailColorProperty = DependencyProperty.Register("FailColor",
            typeof(string),
            typeof(ColorMasking),
            new PropertyMetadata("#FFCCFF"));

    public static readonly DependencyProperty MaskProperty = DependencyProperty.RegisterAttached("Mask",
            typeof(string),
            typeof(ColorMasking),
            new FrameworkPropertyMetadata(OnMaskChanged));
Community
  • 1
  • 1
Nathan Tornquist
  • 6,468
  • 10
  • 47
  • 72

1 Answers1

3

The code you have posted shows that you are registering an AttachedProperty so the PassColorProperty is not a DependencyPropery of your ColorMasking class. It must be accessed through an object that has that attached property set on it. The attached property will allow you to set that property on other objects and not just

    public static void SetPassColor(DependencyObject obj, string passColor)
    {
        obj.SetValue(PassColorProperty, passColor);
    }

    public static string GetPassColor(DependencyObject obj)
    {
        return (string)obj.GetValue(PassColorProperty);
    }

This except from MSDN explains the accessors for an attached property:

The Get Accessor

The signature for the GetPropertyName accessor must be:

public static object Get PropertyName (object target )

-The target object can be specified as a more specific type in your implementation. For example, the DockPanel.GetDock method types the parameter as UIElement, because the attached property is only intended to be set on UIElement instances.

-The return value can be specified as a more specific type in your implementation. For example, the GetDock method types it as Dock, because the value can only be set to that enumeration.

The Set Accessor

The signature for the SetPropertyName accessor must be:

public static void Set PropertyName (object target , object value )

-The target object can be specified as a more specific type in your implementation. For example, the SetDock method types it as UIElement, because the attached property is only intended to be set on UIElement instances.

-The value object can be specified as a more specific type in your implementation. For example, the SetDock method types it as Dock, because the value can only be set to that enumeration. Remember that the value for this method is the input coming from the XAML loader when it encounters your attached property in an attached property usage in markup. That input is the value specified as a XAML attribute value in markup. Therefore there must be type conversion, value serializer, or markup extension support for the type you use, such that the appropriate type can be created from the attribute value (which is ultimately just a string).

evanb
  • 3,061
  • 20
  • 32
  • I've added an edit above. If I change those two properties so they are Register, I still cannot access them from my XAML. Mask and MaskExpression is all that shows up. – Nathan Tornquist May 25 '12 at 17:21
  • Sorry, I didn't notice the xaml in the post. You do need to use them as attached properties and use the getter and setter I wrote in the first code block. – evanb May 25 '12 at 17:28
  • Awesome! It all worked. It confused me how that is possible though. Looking at your code examples, PassColor is named the same as the variable I'm trying to set with my property. SetPassColor and GetPassColor are named differently. Does Visual Studio look for SetXXXXX and GetXXXXX or do those functions not really matter past general form? – Nathan Tornquist May 25 '12 at 18:46
  • It is looking for those specific static methods. I've edited my answer to remove the DependencyProperty part and noted the accessor signatures. – evanb May 25 '12 at 20:39