附件属性无法绑定

Attached property cannot be bound

我们有一个 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>

然而,我的小蓝色波浪线告诉我 "A 'Binding' cannot be used within a 'Border' collection. A 'Binding' can only be set on a DependencyProperty of a DependencyObject." 作为一个大胆的程序员,我大胆地忽略小蓝色波浪线并尝试 运行 无论如何。此时我得到一个例外:

System.Windows.Markup.XamlParseException: 'A 'Binding' 不能设置在类型 'Viewbox' 的 'SetPreviewMouseLeftButtonUpChanged' 属性 上. 'Binding' 只能在 DependencyObject 的 DependencyProperty 上设置。'

原来这是一个命名约定问题。在 copying/pasting/renaming/general 犹豫不决中,我弄乱了命令 属性 的 getter 和 setter 的名称。一旦我将它们全部更改为匹配正确的模式,我的代码就会运行。

#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