Ограничить свойство вложенных зависимостей в wpf - PullRequest
11 голосов
/ 29 июля 2011

Я хочу прикрепить свойство зависимости только к определенным элементам управления.

Если это только один тип, я могу сделать это:

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

(Итак: ограничьте тип Control в методах Get / Set)

Но теперь я хочу разрешить этому свойству присоединяться и к другому типу Control.
Вы попытаетесь добавить перегрузку для обоих методов с этим новым типом, но он не скомпилируется из-за "Неизвестная ошибка сборки, найдено неоднозначное совпадение."

Так, как я могу ограничить свой DependencyProperty выбором Control с?
(Примечание: в моем конкретном случае он мне нужен для TextBox и ComboBox)

1 Ответ

7 голосов
/ 29 июля 2011

Найдено неоднозначное совпадение.

... обычно выбрасывается GetMethod, если имеется несколько перегрузок и не указана сигнатура типа (MSDN: More than one method is found with the specified name.). По сути, WPF-движок ищет только один такой метод.

Почему бы не проверить тип в теле метода и не выдать InvalidOperationException, если это не разрешено?


Обратите внимание, что эти CLR-оболочки не должны включать любой код рядом с настройкой и получением, если свойство установлено в XAML , они будут игнорироваться , попробуйте вызвать исключение в сеттер, он не появится, если вы используете только 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.");
    }
}
...