绑定具体附加值属性

Binding the value of specific attached property

我们的应用程序设计为在以下 3 种模式中的任何一种模式下运行。

public enum Mode
{
    Express,
    Premium,
    Enterprise
}

附加了一个 属性:IsEnabled 根据 Mode 定义。这样我们就可以在 XAML 中设置特定控件是否在该模式下启用。 默认情况下,该控件对所有模式都启用,除非使用该模式的附加 属性 将其明确设置为 false。

<Button x:Name="Button1"
        mode:Enterprise.IsEnabled="False"
        IsEnabled="{Binding SelectedMode}"/>

<Button x:Name="Button2"
        mode:Enterprise.IsEnabled="False"
        mode:Premium.IsEnabled="False"
        IsEnabled="{Binding SelectedMode}"/>

SelectedMode的值属性是以上enum值中的任意一个。现在的问题是如何为该特定模式设置控件 (Button) 的 IsEnabled 属性。

它的一种工作方式是使用 MultiBinding,如下所示,但我觉得它很笨拙。所以想知道是否有更优雅的解决方案来解决这个问题。

<Button x:Name="Button2"
        mode:Enterprise.IsEnabled="False"
        mode:Premium.IsEnabled="False">
        <Button.IsEnabled>
           <MultiBinding Converter="{StaticResource ModeToBooleanConverter}">
              <Binding Path="SelectedMode"/>
              <Binding Path="mode:Enterprise.IsEnabled" RelativeSource="{RelativeSource Self}"/>
              <Binding Path="mode:Premium.IsEnabled" RelativeSource="{RelativeSource Self}"/>
           </MultiBinding>
        </Button.IsEnabled>
</Button>

编辑:

我想要一个解决方案,这样可以减少代码混乱,如下所示,ModeToBooleanConverter 会处理所有事情。

<Button x:Name="Button2"
            mode:Enterprise.IsEnabled="False"
            mode:Premium.IsEnabled="False"
            IsEnabled="{Binding SelectedMode, Converter=ModeToBooleanConverter}"/>

谢谢。

有趣的问题!

我不知道完成这项任务的最佳方式是什么,但在您的情况下,您可以这样做:

<Button x:Name="Button2"
            mode:Enterprise.IsEnabled="False"
            mode:Premium.IsEnabled="False"
            IsEnabled="{Binding RelativeSource={RelativeSource Self}, Converter=ModeToBooleanConverter}"/>

现在,在您的 ModeToBooleanConverter 中,您可以从 Convert 方法的值字段(在您的示例中为 Button)获取附加属性的值和 return 正确的值。

现在等待更好的回应!

我会完全放弃附加的 属性,只是将您允许的模式作为参数传递给转换器。

首先,如果您将模式定义为标志,那么您可以轻松地将模式组合传递给转换器:

[Flags]
public enum AppMode
{
    Express = 1,
    Premium = 2,
    Enterprise = 4,
    PremiumEnterprise = Premium | Enterprise
}

通过允许的模式如下所示:

<Button Content="Premium Only"
        IsEnabled="{Binding SelectedMode, Converter={StaticResource modeConverter},
        ConverterParameter={x:Static local:AppMode.Premium}}" />
<Button Content="Enterprise Only"
        IsEnabled="{Binding SelectedMode, Converter={StaticResource modeConverter},
        ConverterParameter={x:Static local:AppMode.Enterprise}}" />
<Button Content="Premium or Enterprise"
        IsEnabled="{Binding SelectedMode, Converter={StaticResource modeConverter},
        ConverterParameter={x:Static local:AppMode.PremiumEnterprise}}" />

转换器可能看起来像这样:

[ValueConversion(typeof(AppMode), typeof(bool))]
public class AppModeEnabledConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        var selectedMode = (AppMode)value;
        var enabledModes = (AppMode)parameter;
        return 0 != (selectedMode & enabledModes);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}