附件属性无法绑定
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
我们有一个 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