.net-3.5 같은 - WPF에서 반대 부울 속성을 바인딩하는 방법?




강좌 동적 (10)

내가 가진 것은 IsReadOnly 속성을 가진 개체입니다. 이 속성이 true이면 Button의 IsEnabled 속성 (예 IsEnabled 을 false로 설정하고 싶습니다.

나는 IsEnabled="{Binding Path=!IsReadOnly}" 처럼 쉽게 할 수 있다고 믿고 싶습니다 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>

Answers

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


뷰 모델에 속성을 하나 더 추가하면 역방향 값이 반환됩니다. 그리고 버튼에 묶어 라. 처럼;

뷰 모델에서 :

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

xaml :

IsEnabled="{Binding IsNotReadOnly"}

이 것은 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
}

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

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

따라서 컨버터를 작성하는 데 일반적으로 필요한 시간이 빨라집니다.


스탠드 아트 바인딩을 사용하면 약간 바람이 많이 부치는 변환기를 사용해야합니다. 그래서이 프로젝트와 다른 문제를 해결하기 위해 특별히 개발 된 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}" />

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

행운을 빕니다!


나는 반전 문제가 있었지만 깔끔한 해결책을 가지고있었습니다.

XAML 디자이너가 datacontext / no MyValues (itemssource)가 없을 때 빈 컨트롤을 보여 MyValues 동기가있었습니다.

초기 코드 : MyValues 가 비어있는 경우 컨트롤을 숨 깁니다 . 향상된 코드 : MyValues 가 null이 아니거나 비어 있지 않은 경우 컨트롤을 보여줍니다 .

물론 문제는 0 개 항목의 반대 인 '1 개 이상의 항목'을 표현하는 방법입니다.

<ListBox ItemsSource={Binding MyValues}">
  <ListBox.Style x:Uid="F404D7B2-B7D3-11E7-A5A7-97680265A416">
    <Style TargetType="{x:Type ListBox}">
      <Style.Triggers>
        <DataTrigger Binding="{Binding MyValues.Count}">
          <Setter Property="Visibility" Value="Collapsed"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </ListBox.Style>
</ListBox>

나는 그것을 추가함으로써 그것을 해결했다 :

<DataTrigger Binding="{Binding MyValues.Count, FallbackValue=0, TargetNullValue=0}">

바인딩의 기본값을 설정하는 Ergo. 물론 이것은 모든 종류의 역 (inverse) 문제에 대해서는 작동하지 않지만 깨끗한 코드로 나를 도왔습니다.


나는 비슷한 것을했다. 콤보 상자를 선택할 수있는 장면 뒤에서 데이터를 찾은 경우에만 속성을 만들었습니다. 내 윈도우가 처음 나타날 때 비동기 적으로로드 된 명령을 실행하지만 여전히 데이터를로드하는 동안 사용자가 콤보 박스를 클릭하지 않게합니다 (비어있는 경우, 채워집니다). 그래서 기본적으로이 속성은 false이므로 getter의 역함수를 반환합니다. 그런 다음 검색 할 때 속성을 true로 설정하고 완료되면 false로 되돌립니다.

private bool _isSearching;
public bool IsSearching
{
    get { return !_isSearching; }
    set
    {
        if(_isSearching != value)
        {
            _isSearching = value;
            OnPropertyChanged("IsSearching");
        }
    }
}

public CityViewModel()
{
    LoadedCommand = new DelegateCommandAsync(LoadCity, LoadCanExecute);
}

private async Task LoadCity(object pArg)
{
    IsSearching = true;

    //**Do your searching task here**

    IsSearching = false;
}

private bool LoadCanExecute(object pArg)
{
    return IsSearching;
}

그런 다음 콤보 상자의 경우 IsSearching에 직접 바인딩 할 수 있습니다.

<ComboBox ItemsSource="{Binding Cities}" IsEnabled="{Binding IsSearching}" DisplayMemberPath="City" />

@ Paul의 답변에 따라 ViewModel에 다음과 같이 썼습니다.

public bool ShowAtView { get; set; }
public bool InvShowAtView { get { return !ShowAtView; } }

나는 여기있는 발췌 문장을 가지고 누군가를 도울 것, 아마 나는 초보자가되기를 바랍니다.
실수가 있으면 알려주세요.

BTW, 나는 또한 @heltonbiker 의견에 동의합니다 - 당신이 3 번 이상 사용할 필요가없는 경우에만 올바른 접근 방법입니다 ...


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
    }

왜 이런 일이 저에게 일어나지 않았는지 모르겠지만 그 해결책은 너무 단순 해 보입니다.

보기에서 <WebBrowser > 컨트롤을 사용하는 대신 <ContentControl> 사용하고 해당 내용을 ViewModel의 WebBrowser 속성에 바인딩하십시오. ViewModel의 생성자에서 WebBrowser를 만든 다음 브라우저의 탐색 이벤트 (또는 documentloaded)를 ViewModel의 이벤트에 등록 할 수 있습니다.

ViewModel에서 전체 브라우저 컨트롤! 사용자 이벤트를 캡처 할 수도 있습니다. 사용자 이벤트를 캡처하면 ViewModel의 탐색 이벤트에 캡처됩니다.





wpf .net-3.5 styles