WPF-附加属性需要引用另一个绑定的附加属性

WPF-附加属性需要引用另一个绑定的附加属性,wpf,data-binding,attached-properties,Wpf,Data Binding,Attached Properties,我创建了一个附加属性,用于根据特定的枚举值设置UIElement的可见性。这个很好用。但是,我需要扩展它,以便根据发送方的“状态”覆盖可见性 我怎样才能做到这一点?我原以为可以创建第一个附加属性可以引用的另一个附加属性,但是我需要能够将值绑定到第二个附加属性,而不仅仅是设置为枚举值 编辑 下面是我的问题的一个例子: <Window x:Class="AttachedProperty.MainWindow" xmlns="http://schemas.microsoft.com/wi

我创建了一个附加属性,用于根据特定的枚举值设置UIElement的可见性。这个很好用。但是,我需要扩展它,以便根据发送方的“状态”覆盖可见性

我怎样才能做到这一点?我原以为可以创建第一个附加属性可以引用的另一个附加属性,但是我需要能够将值绑定到第二个附加属性,而不仅仅是设置为枚举值

编辑

下面是我的问题的一个例子:

<Window x:Class="AttachedProperty.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:attachedProperty="clr-namespace:AttachedProperty"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel>
        <TextBlock Text="Button should be enabled?"/>
        <CheckBox IsChecked="{Binding Path=CanClick}"/>
        <Button Content="Click Me" IsEnabled="{Binding Path=CanClick}"/>
        <Button Content="Manager Only Click" attachedProperty:SecurityBehavior.IsEnabledRole="Mgr"/>
    </StackPanel>
</Grid>
运行时,两个按钮均已启用-第一个按钮是因为选中了复选框,第二个按钮是因为我是经理。当我取消选中复选框时,第一个按钮将被禁用,我希望我的附加属性只能在正确的安全组中选中复选框时启用


如何根据示例进行更改,以便根据2个可能的输入设置IsEnabled的行为?

不确定为什么要查看此的附加属性。根据您的要求,您可以使用一个简单的
IValueConverter
和一个用于最终控件的
可见性的
绑定来实现这一点

假设我们有一个枚举:

public enum MyEnum {
  StateOne,
  StateTwo
}
和一个
复选框
,例如:

<CheckBox x:Name="chkBox"
          Content="Check Me!!!" />
对于
按钮
,在xaml中:

<StackPanel>
  <StackPanel.Resources>
    <local:MyConverter x:Key="MyConverter" />
  </StackPanel.Resources>
  <CheckBox x:Name="chkBox"
            Content="Check Me!!!" />

  <Button Content="Button One"
          Visibility="{Binding ElementName=chkBox,
                                Path=IsChecked,
                                Converter={StaticResource MyConverter},
                                ConverterParameter={x:Static local:MyEnum.StateOne}}" />

  <Button Content="Button Two"
          Visibility="{Binding ElementName=chkBox,
                                Path=IsChecked,
                                Converter={StaticResource MyConverter},
                                ConverterParameter={x:Static local:MyEnum.StateTwo}}" />

</StackPanel>
和xaml:

<StackPanel>
  <CheckBox x:Name="chkBox"
            Content="Check Me!!!" />
  <Button Content="Button One"
          local:SecurityBehavior.IsEnabled2Role="{Binding ElementName=chkBox,
                                                          Path=IsChecked}"
          local:SecurityBehavior.IsEnabledRole="Mgr" />
  <Button Content="Button Two"
          local:SecurityBehavior.IsEnabled2Role="{Binding ElementName=chkBox,
                                                          Path=IsChecked}"
          local:SecurityBehavior.IsEnabledRole="NotMgr" />
</StackPanel>


我可以按照您的建议使用转换器,但在许多不同的地方都需要使用转换器,尽管转换器可以工作,但我认为如果功能可以包装在附加属性/附加行为中,会使XAML更干净。我不知道我更喜欢在XAML中保留尽可能多的与UI相关的内容可能的如果希望减少复制,则始终可以定义基本
样式
,并在其中分配属性;如果希望进一步降低枚举值,则可以使用自定义DP来保存枚举值。只是对这些东西的附加属性不感兴趣。这就是为什么我们首先得到了绑定、多绑定和转换器:)@DavidWard我编辑了我的答案,并给了你你想要的答案和附加属性。也要考虑另一个选择:谢谢你花时间回答我提出的问题,同时也指出了我为什么要做错事。我一直在盲目地使用附加属性,但使用多绑定转换器,答案就简单多了……谢谢
<StackPanel>
  <StackPanel.Resources>
    <local:MyConverter x:Key="MyConverter" />
  </StackPanel.Resources>
  <CheckBox x:Name="chkBox"
            Content="Check Me!!!" />

  <Button Content="Button One"
          Visibility="{Binding ElementName=chkBox,
                                Path=IsChecked,
                                Converter={StaticResource MyConverter},
                                ConverterParameter={x:Static local:MyEnum.StateOne}}" />

  <Button Content="Button Two"
          Visibility="{Binding ElementName=chkBox,
                                Path=IsChecked,
                                Converter={StaticResource MyConverter},
                                ConverterParameter={x:Static local:MyEnum.StateTwo}}" />

</StackPanel>
public class SecurityBehavior {
  public static readonly DependencyProperty IsEnabledRoleProperty = DependencyProperty.RegisterAttached(
    "IsEnabledRole",
    typeof(string),
    typeof(SecurityBehavior),
    new UIPropertyMetadata(OnIsEnabledRoleChanged));

  public static readonly DependencyProperty IsEnabled2RoleProperty = DependencyProperty.RegisterAttached(
    "IsEnabled2Role",
    typeof(bool),
    typeof(SecurityBehavior),
    new UIPropertyMetadata(OnIsEnabled2RoleChanged));

  private static void OnIsEnabledRoleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
    HandleAttachedPropertyUpdate(sender, (string)e.NewValue, GetIsEnabled2Role(sender));
  }

  private static void OnIsEnabled2RoleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) {
    HandleAttachedPropertyUpdate(sender, GetIsEnabledRole(sender), (bool)e.NewValue);
  }

  private static void HandleAttachedPropertyUpdate(DependencyObject sender, string isEnabledRole, bool isEnabled2Role) {
    sender.SetValue(UIElement.IsEnabledProperty, isEnabledRole == "Mgr" && isEnabled2Role);
  }

  public static void SetIsEnabledRole(DependencyObject element, string value) {
    element.SetValue(IsEnabledRoleProperty, value);
  }

  public static string GetIsEnabledRole(DependencyObject element) {
    return (string)element.GetValue(IsEnabledRoleProperty);
  }

  public static void SetIsEnabled2Role(DependencyObject element, bool value) {
    element.SetValue(IsEnabled2RoleProperty, value);
  }

  public static bool GetIsEnabled2Role(DependencyObject element) {
    return (bool)element.GetValue(IsEnabled2RoleProperty);
  }
}
<StackPanel>
  <CheckBox x:Name="chkBox"
            Content="Check Me!!!" />
  <Button Content="Button One"
          local:SecurityBehavior.IsEnabled2Role="{Binding ElementName=chkBox,
                                                          Path=IsChecked}"
          local:SecurityBehavior.IsEnabledRole="Mgr" />
  <Button Content="Button Two"
          local:SecurityBehavior.IsEnabled2Role="{Binding ElementName=chkBox,
                                                          Path=IsChecked}"
          local:SecurityBehavior.IsEnabledRole="NotMgr" />
</StackPanel>