在MarkupExtension中使用DependencyProperty

11

MarkupExtension派生类中,是否可以拥有一个DependencyProperty

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
        }
    }
}

该扩展名用于以下代码片段。

<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>

是否有可能构建这样的扩展程序,还是我只是在白费力气?(上面的代码无法编译和运行,但我在这里发布它以最好地说明问题。)

3个回答

5
不,你只能将依赖属性添加到派生自DependencyObject的类中,MarkupExtension直接从Object派生。

那么绑定标记扩展怎么样?它的属性可以单独绑定,因此它们是依赖属性。 - Narek Malkhasyan
@Narek - 根据MSDN的说法,绑定标记扩展没有依赖属性,这是有道理的,因为你不能在不调用DependencyObject.SetValue和DependencyObject.GetValue的情况下实现依赖属性,而你不能在不从DependencyObject继承的情况下调用它们。此外,我现在无法测试,但我认为你不能在绑定自己的属性上使用绑定,也就是说,你不能做{Binding Converter={Binding ...}}。 - Nir
实际上我没有WPF的经验,但在Silverlight 5中,绑定自身属性是完全可行的。这里有一个例子:"{Binding UserName, RelativeSource={RelativeSource FindAncestor, AncestorType=UserControl}}"。 - Narek Malkhasyan
1
@Narek {RelativeSource}不是数据绑定,而是一种不同的标记扩展,其工作方式不同,并且可以在非依赖属性上工作。{Binding}仅适用于依赖属性,因此无法在标记扩展上使用。 - Nir
你是对的,我错误地假设Binding标记扩展的属性应该像其他标记扩展一样成为依赖属性。 - Narek Malkhasyan

0

是的..这是一个棘手的问题..但它有一个简单而不直观的答案。 创建另一个标记扩展来获取静态资源。 所以,不要使用{StaticResource shapesDS}

您将创建一个名为DataSetLocator的新MarkupExtension

我不会写代码,但Provide value需要根据名称或其他输入返回数据集。

然后,您可以更改xaml,使您的扩展使用数据集定位器扩展示例Source="{DataSetLocator name=shapesDS }"

很遗憾扩展不扩展DependencyProperty,但它们不会。


-1

只需使用IMarkupExtension而不是MarkupExtension,您就可以扩展DependencyObject。至少在Silverlight 5中,您可以这样做,但我认为WPF也有它。


7
WPF没有IMarkupExtension。 - Brian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接