2014-02-21 2 views
1

특정 열거 형 값을 기반으로 UIElement의 표시 여부를 설정하기 위해 연결된 속성을 만들었습니다. 이것은 잘 작동합니다. 그러나 발신자의 "상태"를 기준으로 표시 여부를 재정의 할 수 있도록 확장해야합니다.WPF - 연결된 속성이 다른 바운드 연결된 속성을 참조해야합니다.

어떻게하면됩니까? 나는 첨부 된 첫 번째 속성이 참조 할 수있는 다른 연결된 속성을 만들 수 있다고 생각했지만 enum 값으로 설정하는 대신 두 번째 연결된 속성에 값을 바인딩 할 수 있어야합니다.

편집 아래

내 문제의 예입니다

<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 속성은 체크 박스를 사용하여 제어된다. 1을 확인란이 선택되어 있기 때문에 두 번째 난을이기 때문에 - 두 버튼이 활성화 실행하면

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

왜이 기능에 대한 첨부 속성을 사용했는지 잘 모름 귀하의 요구 사항을 바탕으로 최종 제어의 Visibility에 대한 간단한 IValueConverterBinding을 사용하여이 문제를 해결할 수 있습니다.

그래서 우리는 열거가 있다고 :

public enum MyEnum { 
    StateOne, 
    StateTwo 
} 

CheckBox 같은 : 이제 우리는 열거가 StateOne하고있을 때 일부 ButtonVisibility으로 만 볼 수 원하는 경우

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

확인란을 선택하면

와 같이 변환기를 사용할 수 있습니다.

Button 's의

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에서: 체크 박스는, 그러나 버튼을 체크하면

이와
<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입니다.

당신이 Button의 제어 할 IsEnabled 상태가 있다면, 단지 열거 값을 제공하기 위해 단지 따라 대신 Visibility.Visible

의 당신이 선택하는 경우에도 true 또는 false를 반환하는 속성 및 컨버터에서 바인딩을 전환

: 그냥 Binding MultiBinding을하고 IMultiValueConverter

업데이트에 IValueConverter을 전환 할 수없는 정적 및 동적

어떤 이유로 든 연결된 속성의 경로를 따라 가야하는 경우 연결된 각 속성의 속성 변경 콜백이 보낸 사람의 다른 속성 값을 가져 와서 그에 따라 논리를 수행합니다.

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 관련 항목을 많이 유지하는 것을 선호합니다. 당신은 언제나베이스 스타일을 정의 할 수 있으며 복제를 줄이기 원한다면 속성을 할당 할 수 있습니다. 이 물건들에 붙어있는 속성들에 매료되지 않았습니다. 그래서 우리는 Binding과 MultiBinding 및 변환기를 처음부터 가지고 있습니다. – Viv

+1

@DavidWard 제 대답을 편집하고 첨부 된 속성을 사용하여 찾고 있던 대답을 제공했습니다. :) 다른 옵션도 고려해보십시오 :) – Viv

관련 문제