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

时间:2014-02-21 12:04:11

标签: wpf data-binding attached-properties

我创建了一个附加属性,用于根据特定的枚举值设置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>

使用复选框控制第一个按钮的启用属性。 第二个按钮的enabled属性由attachmentProperty控制,该属性确定您是否在正确的安全组中:

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

    private static void OnIsEnabledRoleChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {
        // In here have some logic that determines if the current user is authorised
        // Principal.IsInRole(e.NewValue.ToString() ? true : false;
        sender.SetValue(UIElement.IsEnabledProperty, true);
    }

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

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

当运行时,两个按钮都被启用 - 第一个因为复选框被选中而第二个因为我是一个经理。当我取消选中该复选框时,第一个按钮被禁用,我希望我的附加属性只能在正确的安全组 AND 中选中该复选框。

如何通过示例进行更改,以便我可以获得基于2个可能输入设置IsEnabled的行为?

1 个答案:

答案 0 :(得分:1)

不确定为什么你要为此附加属性。根据您的要求,您可以使用简单的IValueConverterBinding来获取最终控件的Visibility

所以说我们有一个枚举:

public enum MyEnum {
  StateOne,
  StateTwo
}

CheckBox,例如:

<CheckBox x:Name="chkBox"
          Content="Check Me!!!" />

现在,如果我们想要一些Button的{​​{1}}仅在枚举为Visibility时显示,并且选中了复选框,

我们可能只有一个转换器,如:

StateOne

和xaml中的public class MyConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var checkBoxIsChecked = (bool)value; var givenEnum = (MyEnum)parameter; return checkBoxIsChecked && givenEnum == MyEnum.StateOne ? Visibility.Visible : Visibility.Collapsed; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } }

Button

这样,当选中复选框时,“按钮1”将变为可见,但是按钮2不会因为按钮2传递的<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> ConverterParameter而无法显示。

如果它是你要控制StateTwo的{​​{1}}状态,只需将绑定切换到该属性,并在转换器中相应地返回true或false而不是IsEnabled

即使您选择提供非静态和动态的枚举值,您也可以将Button设为Visibility.Visible并将Binding切换为MultiBinding

<强>更新

如果由于某种原因您必须沿着附加属性的路线走下去,那么在属性中,每个附加属性的更改回调都会从发送方获取其他属性值并相应地执行您的逻辑。

IValueConverter

和xaml:

IMultiValueConverter