2014-02-21 155 views
1

我已經創建了一個附加屬性來設置基於特定枚舉值的UIElement的可見性。這工作正常。但是,我需要擴展這一點,以便根據發件人的「狀態」覆蓋可見性。WPF - 附屬性需要引用另一個綁定附加屬性

我該如何做到這一點?我曾想過我可以創建另一個附屬屬性,第一個附屬屬性可以引用,但是我需要能夠將值綁定到第二個附加屬性,而不是隻設置爲枚舉值。

編輯

下面是我的問題的一個例子:使用複選框只是控制

<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屬性。第一,因爲該複選框被選中,第二,因爲我是一個 -

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

當運行這兩個按鈕被激活: 第二個按鈕的enabled屬性被確定,如果你是正確的安全組中的attachedProperty控制經理。當我取消選中複選框時,第一個按鈕處於禁用狀態,我希望我的附加屬性僅在安全組中的複選框處於選中狀態時才能啓用。

如何通過樣本進行更改,以便我可以獲得基於2個可能輸入設置IsEnabled的行爲?

回答

1

不確定爲什麼你要爲此附加屬性。根據您的要求,您可以使用簡單的IValueConverterBinding來實現最終控制的Visibility

所以說,我們有一個枚舉:

public enum MyEnum { 
    StateOne, 
    StateTwo 
} 

CheckBox如:

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

現在,如果我們想要一些ButtonVisibility僅當枚舉是StateOne和可見覆選框被選中,

我們可以只有一個轉換器,如:

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

,並在XAML爲Button的:

<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

如果這是你想要控制ButtonIsEnabled狀態,只是切換綁定到財產,並在轉換器只返回true或false,而不必援用Visibility.Visible

即使您選擇提供枚舉值不是靜態的,動態的,你可以只作一個BindingMultiBinding切換IValueConverterIMultiValueConverter

更新:

如果出於任何原因必須沿着附加屬性的路線行進,那麼在屬性中更改每個附加屬性的回調從發件人獲取其他屬性值並相應地執行您的邏輯。

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

和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> 
+0

按照你的建議我可以用一個轉換器,但會有很多不同的地方,這將需要,雖然轉換器會工作,我認爲這將使XAML更清潔,如果功能可能被包裹在一個附加的屬性/附加行爲 –

+0

我不知道我更喜歡儘可能保持在xaml UI相關的東西儘可能。如果你想減少複製或者讓自定義DP保持枚舉值,如果你想進一步降低複製值,你總是可以定義一個基類'Style'並在那裏分配屬性。只是沒有吸引到這些東西附加屬性。這就是爲什麼我們將Binding和MultiBinding和轉換器放在第一位:) – Viv

+1

@DavidWard我已經編輯了我的答案,並給出了您正在尋找的附加屬性的答案。請考慮其他選項:) – Viv