2016-02-09 157 views
2

我們的應用程序設計用於以下三種模式中的任何一種模式。綁定特定附加屬性的值

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值中的任何一個。現在的問題是如何爲該特定模式設置控件的IsEnabled屬性(Button)。

它可以工作的一種方法是使用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}"/> 

謝謝。

回答

2

我會完全放棄附屬屬性,只是將您的允許模式作爲參數傳遞給轉換器。

首先,如果你定義模式爲標誌,那麼你可以很容易地通過模式的組合轉換器:

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

很好的答案。在我的情況下唯一的問題是枚舉沒有FlagAttribute,枚舉來自另一個我無法控制的庫。 'enum's不能被繼承 – Marshal

1

有趣的問題!

我不知道這是完成這一任務的最佳方式,但在你的情況,你可以做這樣的事情:

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

現在您的ModeToBooleanConverter你可以得到附加的價值來自Convert方法(在你的例子中的一個Button)的值字段的屬性並返回適當的值。

現在等待更好的回覆!

+0

我仍然需要綁定'SelectedMode'屬性來通知控制如果模式已經改變,所以我想用'ConverterParameter'傳遞對象(控件)。 – Marshal

+0

我認爲不能在ConverterParameter中使用SelectedMode,因爲ConverterParameter不可綁定,所以我的回答沒用;-) – Giangregorio

+0

不,但我們可以將對象本身作爲'ConverterParameter'傳遞。 'IsEnabled =「{Binding SelectedMode.Value,Converter = {StaticResource ModeToBooleanConverter},ConverterParameter = {RelativeSource Self}}」' – Marshal