简体   繁体   中英

Binding the value of specific attached property

Our application is designed to operate in any one of the following 3 modes.

public enum Mode
{
    Express,
    Premium,
    Enterprise
}

There is one attached property: IsEnabled defined per Mode . So that we can set in XAML if a particular control is enabled or not in that mode. By default the control is enabled for all modes, unless it is explicitly set to false using the attached property for that mode.

<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}"/>

The value of SelectedMode property is any one of the above enum value. Now the question is how to set IsEnabled property of the control ( Button ) for that particular mode.

One way it can work is using MultiBinding as below, but I find it clumsy. So was wondering if there is a more elegant solution to work with this problem.

<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>

Edit:

I would like to have a solution such that the code clutter is reduced as shown below and ModeToBooleanConverter takes care of everything.

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

Thank you.

I would drop the attached property altogether and just pass your allowable modes as a parameter to the converter.

First, if you define your modes as flags then you can pass combinations of modes easily to the converter:

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

Passing the allowable modes then looks like this:

<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}}" />

And the converter might look something like this:

[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();
    }
}

Interesting question!

I don't know which is the best way to accomplish this task, but in your case you can do something like this:

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

Now in your ModeToBooleanConverter you can get the the value of the attached properties from the value field of the Convert method (a Button in your example) and return the proper value.

Now wait for a better response!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM