Тип присоединенного свойства WPF обрабатывается платформой - PullRequest
0 голосов
/ 03 июля 2019

Рассмотрим в значительной степени стандартное свойство Attached для некоторого производного типа:

public class DerivedKeyBinding : KeyBinding
{
    public string Name; //shortened, make this propdp
}

public class KeyBindingExtenstions
{
    public static DerivedKeyBinding GetCommand(DependencyObject obj) {
        return (DerivedKeyBinding)obj.GetValue(CommandProperty);
    }

    public static void SetCommand(DependencyObject obj, DerivedKeyBinding value) {
        obj.SetValue(CommandProperty, value);
    }

    public static readonly DependencyProperty CommandProperty =
        DependencyProperty.RegisterAttached("Command", typeof(DerivedKeyBinding), typeof(KeyBindingExtenstions), new UIPropertyMetadata(null, CommandChanged));

    private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) {
        var commandValue = GetCommand(d);
    }
}

, которое позже устанавливается в XAML:

<Grid>
    <Grid.Style>
        <Style>
            <Setter Property="local:KeyBindingExtenstions.Command">
                <Setter.Value>
                    <local:DerivedKeyBinding Name="{Binding Title, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}"/>
                </Setter.Value>
            </Setter>
        </Style>
    </Grid.Style>
</Grid>

Это, однако, приведет к сбою var commandValue = GetCommand(d);строка из-за local:DerivedKeyBinding потеряна для KeyBinding где-то в процессе.
По какой-то странной причине свойство типа DerivedKeyBinding устанавливается со значением типа KeyBinding (даже если значение явно установите DerivedKeyBinding в XAML).

System.InvalidCastException: 'Невозможно привести объект типа' System.Windows.Input.KeyBinding 'к типу' AttachedPropertyInStyle.DerivedKeyBinding '.'

Почему это происходит и как я могу исправить проблему?


Кажется, проблема связана с привязкой Name - если это статическое значение, код выполняетсябезотказно.

1 Ответ

1 голос
/ 03 июля 2019

Переопределить Key​Binding.​Create​Instance​Core. От Документы Microsoft :

Примечания для наследников

Каждый производный класс Freezable должен реализовывать этот метод. Типичная реализация - просто вызвать конструктор по умолчанию и вернуть результат.


public class DerivedKeyBinding : KeyBinding
{
    ...

    protected override Freezable CreateInstanceCore()
    {
        return new DerivedKeyBinding();
    }
}

В PropertyChangedCallback вы также можете написать:

var commandValue = (DerivedKeyBinding)e.NewValue;
...