WPF에서 역 부울 속성을 바인딩하는 방법은 무엇입니까?

내가 가진 것은 IsReadOnly속성 이있는 객체입니다 . 이 속성이 true이면 IsEnabledButton 의 속성 (예 :)을 false 로 설정하고 싶습니다 .

나는 그것을 쉽게 할 수 있다고 생각하고 IsEnabled="{Binding Path=!IsReadOnly}"싶지만 WPF와 함께 비행하지는 않습니다.

모든 스타일 설정을 거쳐야합니까? 하나의 bool을 다른 bool의 역수로 설정하는 것만 큼 단순한 단어로는 너무 장황한 것처럼 보입니다.

<Button.Style>
    <Style TargetType="{x:Type Button}">
        <Style.Triggers>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="True">
                <Setter Property="IsEnabled" Value="False" />
            </DataTrigger>
            <DataTrigger Binding="{Binding Path=IsReadOnly}" Value="False">
                <Setter Property="IsEnabled" Value="True" />
            </DataTrigger>
        </Style.Triggers>
    </Style>
</Button.Style>



답변

bool 속성을 반전시키는 ValueConverter를 사용할 수 있습니다.

XAML :

IsEnabled="{Binding Path=IsReadOnly, Converter={StaticResource InverseBooleanConverter}}"

변환기:

[ValueConversion(typeof(bool), typeof(bool))]
    public class InverseBooleanConverter: IValueConverter
    {
        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            if (targetType != typeof(bool))
                throw new InvalidOperationException("The target must be a boolean");

            return !(bool)value;
        }

        public object ConvertBack(object value, Type targetType, object parameter,
            System.Globalization.CultureInfo culture)
        {
            throw new NotSupportedException();
        }

        #endregion
    }


답변

IsNotReadOnly부동산 을 고려 했습니까 ? 바인딩되는 객체가 MVVM 도메인의 ViewModel 인 경우 추가 속성이 완벽합니다. 직접 엔터티 모델 인 경우 엔터티의 특수한 ViewModel을 구성하고 양식에 제시 할 수 있습니다.


답변

표준 바인딩을 사용하면 바람이 거의 부는 것처럼 보이지 않는 변환기를 사용해야합니다. 따라서이 문제와 다른 문제를 해결하기 위해 특별히 개발 된 CalcBinding 프로젝트를 보는 것이 좋습니다 . 고급 바인딩을 사용하면 많은 소스 속성이있는 표현식을 xaml에 직접 작성할 수 있습니다. 다음과 같이 작성할 수 있습니다.

<Button IsEnabled="{c:Binding Path=!IsReadOnly}" />

또는

<Button Content="{c:Binding ElementName=grid, Path=ActualWidth+Height}"/>

또는

<Label Content="{c:Binding A+B+C }" />

또는

<Button Visibility="{c:Binding IsChecked, FalseToVisibility=Hidden}" />

where A, B, C, IsChecked-viewModel의 속성과 제대로 작동합니다


답변

https://quickconverter.codeplex.com/을 사용하는 것이 좋습니다.

부울 반전은 다음과 같이 간단합니다.
<Button IsEnabled="{qc:Binding '!$P', P={Binding IsReadOnly}}" />

이는 일반적으로 변환기를 작성하는 데 필요한 시간을 단축시킵니다.


답변

XAML을 가능한 한 우아하게 유지하고 싶었으므로 공유 라이브러리 중 하나에있는 bool을 래핑하는 클래스를 만들었습니다. 암시 적 연산자는 클래스를 코드 숨김에서 부울로 원활하게 사용할 수 있도록합니다.

public class InvertableBool
{
    private bool value = false;

    public bool Value { get { return value; } }
    public bool Invert { get { return !value; } }

    public InvertableBool(bool b)
    {
        value = b;
    }

    public static implicit operator InvertableBool(bool b)
    {
        return new InvertableBool(b);
    }

    public static implicit operator bool(InvertableBool b)
    {
        return b.value;
    }

}

프로젝트에 필요한 유일한 변경 사항은 반전하려는 속성이 bool 대신 이것을 반환하도록하는 것입니다.

    public InvertableBool IsActive
    {
        get
        {
            return true;
        }
    }

XAML 접두사에서 Value 또는 Invert를 사용한 바인딩

IsEnabled="{Binding IsActive.Value}"

IsEnabled="{Binding IsActive.Invert}"


답변

이것은 nullable bool에도 적용됩니다.

 [ValueConversion(typeof(bool?), typeof(bool))]
public class InverseBooleanConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (targetType != typeof(bool?))
        {
            throw new InvalidOperationException("The target must be a nullable boolean");
        }
        bool? b = (bool?)value;
        return b.HasValue && !b.Value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return !(value as bool?);
    }

    #endregion
}


답변

뷰 모델에 속성을 하나 더 추가하면 역값이 반환됩니다. 그리고 버튼에 바인딩하십시오. 처럼;

뷰 모델에서 :

public bool IsNotReadOnly{get{return !IsReadOnly;}}

xaml에서 :

IsEnabled="{Binding IsNotReadOnly"}