11

Is it possible to have a DependencyProperty within a MarkupExtension derived class?

public class GeometryQueryExtension : MarkupExtension
{
    public XmlDataProvider Source { get; set; }

    public string XPath { get; set; }

    public static readonly DependencyProperty ArgumentProperty = DependencyProperty.RegisterAttached(
        "Argument",
        typeof(string),
        typeof(GeometryQueryExtension)); // this wont work because GeometryQueryExtension is not a DependencyProperty

    public string Argument
    {
        get
        {
            return (string)GetValue(ArgumentProperty); // this wont even compile because GeometryQueryExtension doesnt derive from a class which has GetValue
        }
        set
        {
            SetValue(ArgumentProperty,value);// this wont even compile because GeometryQueryExtension doesnt derive from a class which has SetValue
        }
    }
}

The extension is used in the following snippet.

<Label.Content>
    <local:GeometryQueryExtension Source="{StaticResource shapesDS}">
        <local:GeometryQueryExtension.XPath>
            /Shapes/Geometry/{0}
        </local:GeometryQueryExtension.XPath>
        <local:GeometryQueryExtension.Argument>
            <Binding XPath="Geometry"/> <!-- will throw exception when processing this bind -->
        </local:GeometryQueryExtension.Argument>
    </local:GeometryQueryExtension>
</Label.Content>

Is it even possible to build such an extension or am i just barking up the wrong tree ? (the code above wont compile and run, but i posted it here to best illustrate the problem).

Dave Clemmer
  • 3,741
  • 12
  • 49
  • 72
Andrew Keith
  • 7,515
  • 1
  • 25
  • 41

3 Answers3

5

No, you can only add dependency properties to classes that are derived from DependencyObject, MarkupExtention is derived directly from Object

Nir
  • 29,306
  • 10
  • 67
  • 103
  • In that case what about the binding markup extension? It's properties can be bound on their own, so they are dependency properties. – Narek Malkhasyan Aug 21 '12 at 06:58
  • @Narek - according to MSDN the binding markup extension does not have dependency properties, this makes sense because you can't implement dependency properties without calling DependencyObject.SetValue and DependencyObject.GetValue and you can't call those without inheriting from DependencyObject. also, I can't test it right now but I don't think you can use binding on binding's own properties, that is you can't do {Binding Converter={Binding ...}} – Nir Aug 21 '12 at 07:21
  • Actually I don't have any experience in WPF, but in Silverlight 5 it is definitely possible to use binding on binding's own properties. Here is an example: "{Binding UserName, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}". – Narek Malkhasyan Aug 22 '12 at 08:21
  • 1
    @Narek {RelativeSource} is not data binding, it is a different markup extension that works differently and can work on non-dependency properties, {Binding} only works on dependency properties and so doesn't work on markup extensions – Nir Aug 22 '12 at 09:32
  • You are right, I was mistakenly assuming that properties of Binding markup extension should be dependency properties as other markup extensions are applied on them. – Narek Malkhasyan Aug 22 '12 at 09:50
0

Yea.. it’s an ugly problem.. However it has a simple non intuitive answer. Create another markup extension to get the static resource. So instead of using {StaticResource shapesDS}

You would create a new MarkupExtension called DataSetLocator

I'm not going to write the code but the Provide value would need to return your dataset based on a name or some other input.

Then you change your xaml to have your extension use the dataset locator extension example Source="{DataSetLocator name=shapesDS }"

It’s too bad that extensions don’t extend DependencyProperty but they don’t.

slfan
  • 8,950
  • 115
  • 65
  • 78
cgrow
  • 1
-1

Just use IMarkupExtension instead of MarkupExtension and you can extend DependencyObject. At least in Silverlight 5 you can, but I would assume WPF also has it.

Didier A.
  • 4,609
  • 2
  • 43
  • 45