Присоединенное свойство не может быть связано - PullRequest
0 голосов
/ 30 октября 2019

У нас есть приложение WPF, у которого на экране отображается результат подсчета запросов. Сначала мы определили результат как кнопку, чтобы при нажатии на нее приложение отображало подробный список результатов запроса. Однако по причинам, не связанным с этим вопросом, теперь нам нужно, чтобы это была граница (в основном, просто шаблон для исходной кнопки). До сих пор я установил свое присоединенное свойство:

public static class AttachedCommandBehavior
{
    #region Command

    public static DependencyProperty PreviewMouseLeftButtonUpCommandProperty = DependencyProperty.RegisterAttached(
        "PreviewMouseLeftButtonUpCommand",
        typeof(ICommand),
        typeof(AttachedCommandBehavior),
        new FrameworkPropertyMetadata(PreviewPreviewMouseLeftButtonUpChanged));

    public static void SetPreviewMouseLeftButtonUpChanged(DependencyObject target, ICommand value)
    {
        target.SetValue(PreviewMouseLeftButtonUpCommandProperty, value);
    }

    public static ICommand GetPreviewMouseLeftButtonUpChanged(DependencyObject target)
    {
        return (ICommand)target.GetValue(PreviewMouseLeftButtonUpCommandProperty);
    }

    private static void PreviewPreviewMouseLeftButtonUpChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is UIElement element)
        {
            if (e.NewValue != null && e.OldValue == null)
            {
                element.PreviewMouseLeftButtonUp += element_PreviewMouseLeftButtonUp;
            }
            else if (e.NewValue == null && e.OldValue != null)
            {
                element.PreviewMouseLeftButtonUp -= element_PreviewMouseLeftButtonUp;
            }
        }
    }

    private static void element_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (sender is UIElement element)
        {
            if (element.GetValue(PreviewMouseLeftButtonUpCommandProperty) is ICommand command)
                command.Execute(CommandParameterProperty);
        }
    }

    #endregion

    #region CommandParameter

    public static DependencyProperty CommandParameterProperty = DependencyProperty.RegisterAttached(
        "CommandParameter",
        typeof(object),
        typeof(AttachedCommandBehavior),
        new FrameworkPropertyMetadata(CommandParameterChanged));

    public static void SetCommandParameter(DependencyObject target, object value)
    {
        target.SetValue(CommandParameterProperty, value);
    }

    public static object GetCommandParameter(DependencyObject target)
    {
        return target.GetValue(CommandParameterProperty);
    }

    private static void CommandParameterChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (d is UIElement element)
        {
            element.SetValue(CommandParameterProperty, e.NewValue);
        }
    }

    #endregion
}

И затем в своем XAML я пытаюсь привязать свою команду к присоединенному свойству DependencyProperty:

<Border Background="{Binding BackgroundColor, Converter={StaticResource ColorNameToBrushConverter}}"
        Cursor="{x:Static Cursors.Hand}"
        local:AttachedCommandBehavior.PreviewMouseLeftButtonUpChanged="{Binding QueryClickedCommand}">
   <Grid>...</Grid>
</Border>

Однако моймаленькая голубая волнистая линия говорит мне: «Связывание» нельзя использовать в коллекции «Граница». «Связывание» можно установить только для свойства DependencyProperty объекта DependencyObject. »Будучи дерзким программистом, я смело игнорирую маленькую голубую волнистость и пытаюсь все равно бежать. В этот момент я получаю исключение:

System.Windows.Markup.XamlParseException : «Связывание» не может быть установлено в свойстве «SetPreviewMouseLeftButtonUpChanged» типа «Viewbox». «Связывание» может быть установлено только для свойства DependencyProperty объекта DependencyObject. '

1 Ответ

0 голосов
/ 30 октября 2019

Оказывается, это была проблема соглашения об именах. При копировании / вставке / переименовании / общей нерешительности я перепутал имена моего метода получения и установки для свойства команды. Как только я изменил их все в соответствии с правильным шаблоном, мой код запускается.

#region Command

public static DependencyProperty PreviewMouseLeftButtonUpCommandProperty = DependencyProperty.RegisterAttached(
            "PreviewMouseLeftButtonUpCommand",
            typeof(ICommand),
            typeof(AttachedCommandBehavior),
            new FrameworkPropertyMetadata(PreviewMouseLeftButtonUpChanged));

public static void SetPreviewMouseLeftButtonUpCommand(DependencyObject target, ICommand value)
{
    target.SetValue(PreviewMouseLeftButtonUpCommandProperty, value);
}

public static ICommand GetPreviewMouseLeftButtonUpCommand(DependencyObject target)
{
    return (ICommand)target.GetValue(PreviewMouseLeftButtonUpCommandProperty);
}

private static void PreviewMouseLeftButtonUpChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    if (d is UIElement element)
    {
        if (e.NewValue != null && e.OldValue == null)
        {
            element.PreviewMouseLeftButtonUp += element_PreviewMouseLeftButtonUp;
        }
        else if (e.NewValue == null && e.OldValue != null)
        {
            element.PreviewMouseLeftButtonUp -= element_PreviewMouseLeftButtonUp;
        }
    }
}

private static void element_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    if (sender is UIElement element)
    {
        if (element.GetValue(PreviewMouseLeftButtonUpCommandProperty) is ICommand command)
            command.Execute(CommandParameterProperty);
    }
}

#endregion
...