WPF中限制附加依赖属性

15

我希望只将依赖属性附加到特定的控件上。

如果只是针对一种类型的控件,我可以这样做:

public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.RegisterAttached("MyProperty", typeof(object), typeof(ThisStaticWrapperClass));

public static object GetMyProperty(MyControl control)
{
    if (control == null) { throw new ArgumentNullException("control"); }

    return control.GetValue(MyPropertyProperty);
}

public static void SetMyProperty(MyControl control, object value)
{
    if (control == null) { throw new ArgumentNullException("control"); }

    control.SetValue(MyPropertyProperty, value);
}

(因此:限制在Get/Set方法中的Control类型)

但现在我想要允许该属性附加到不同类型的Control上。
你可以尝试为这个新类型添加两种方法的重载,但由于"Unknown build error, Ambiguous match found."而无法编译。

那么,我如何将我的DependencyProperty限制为一组Control
(注意:在我特定的情况下,我需要它用于TextBoxComboBox)


请问,如果您有两个方法SetMyProperty(TextBox control, object value)SetMyProperty(ComboBox control, object value),是否会出现错误?如果是这样,那么这可能是附加属性系统的限制。如果是这样,除了将其附加到最大公共基类并在附加到不受支持的控件类型时引发异常之外,可能没有其他解决方法... - user1228
@Will - 是的,那就是我尝试过的 =( 那样不好,所以我必须首先为所有的“控件”_“允许”它... - ordag
1个回答

8

找到了多个模糊匹配项。

如果存在多个重载且未指定类型签名,则 GetMethod 通常会抛出此异常(MSDN:More than one method is found with the specified name.)。基本上,WPF 引擎只在寻找一个这样的方法。

为什么不在方法体中检查类型并抛出 InvalidOperationException(无效操作异常),如果不允许呢?


请注意,CLR-Wrappers除了设置和获取属性以外不应包含任何代码。如果属性在XAML中设置,则它们将被忽略。尝试在setter中抛出异常,如果您仅使用XAML设置值,则不会弹出异常。 相反,请使用回调来解决:
public static readonly DependencyProperty MyPropertyProperty =
    DependencyProperty.RegisterAttached
        (
            "MyProperty",
            typeof(object),
            typeof(ThisStaticWrapperClass),
            new UIPropertyMetadata(null, MyPropertyChanged) // <- This
        );

public static void MyPropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
{
    if (o is TextBox == false && o is ComboBox == false)
    {
        throw new InvalidOperationException("This property may only be set on TextBoxes and ComboBoxes.");
    }
}

抛出异常是强制执行的一种可能方式,但我会失去编辑器自动完成支持(在VS中),因为在这种情况下它仍然会显示每个控件。 - ordag
你确定在XAML数据绑定中MyPropertyChanged方法会被调用吗?依赖属性系统会绕过DP的getter/setter(常规的,而不是附加的)。如果这也适用于附加DP,则需要在处理附加属性时抛出异常。 - user1228
2
@Will:回调函数将在所有更改时被调用,无论是通过绑定、在XAML中设置还是调用Set方法。 - H.B.
哦,好的,我已经在使用属性更改回调进行进一步操作了。所以我现在正在尝试过滤掉不需要的控件。 - ordag
@ordag:这只是附加属性的限制之一,我认为你无法做太多事情。(Blend互动性在尝试将TriggerAction<T>附加到除T以外的其他内容时也会引发异常) - H.B.
显示剩余2条评论

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