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