【问题标题】:Attached property cannot be bound无法绑定附加属性
【发布时间】:2020-02-25 13:07:06
【问题描述】:

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

但是,我的蓝色波浪线告诉我“不能在 'Border' 集合中使用 'Binding'。'Binding' 只能在 DependencyObject 的 DependencyProperty 上设置。”作为一个大胆的程序员,我大胆地忽略了小蓝色波浪并尝试运行。在这一点上我得到一个例外:

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

【问题讨论】:

    标签: c# wpf xaml dependency-properties attached-properties


    【解决方案1】:

    原来这是一个命名约定问题。在复制/粘贴/重命名/一般犹豫不决时,我弄乱了命令属性的 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
    

    【讨论】:

    • 请注意完全确定它已被标记,但它帮助我解决了我的问题。我唯一要补充的是更清楚地说明哪些部分不同步。
    猜你喜欢
    • 2011-12-26
    • 2017-07-02
    • 2011-02-07
    • 1970-01-01
    • 1970-01-01
    • 2011-11-01
    • 2011-02-14
    • 2015-10-29
    • 1970-01-01
    相关资源
    最近更新 更多