를 사용하는 방법 RX 하 제어 명령의 가용성에서는 복잡한 시나리오?

0

질문

설치

가정하자 다음과 같습니다. 우리는 다음과 같은 이론적 뷰 모델 클래스는 응용 프로그램 WPF:

public MyViewModel
{

    public MyViewModel()
    {
        // Condition under which this command may be executed is:
        // this.ActiveDocument.Highlighting.Type == Highlighting.Xml && 
        //    !this.ActiveDocument.IsReadOnly && 
        //    (this.License.Kind == LicenseKind.Full || this.License.TrialDay < 30)
        MyCommand = new Command(obj => DoSomething());
    }

    public ICommand MyCommand { get; } 
    // (all other required properties)
}

또한 다음 사항에 주의합니다.

  • 현재 클래스를 구현하는 올바 INotifyPropertyChanged
  • 모든 클래스에서 구성원의 액세스 체인에 제대로 구현 INotifyPropertyChanged (예를 들어. 문서 뷰 모델에서 액세스 ActiveDocument 성)
  • ActiveDocumentnull. ActiveDocument.Highlighting 수도 있습 null 입니다.

문제

나는 다음과 같은 명령하는 경우에만 사용하는 조건에 코멘트를 충족시킬 수 있습니다.

지 않고 옵션 RX

내가 쓴 나 자신의 라이브러리를 처리하기 위한 이러한 상황입니다. 이 솔루션은 것 중 하나:

public MyViewModel
{
    private readonly Condition commandAvailableCondition;

    public MyViewModel()
    {
        commandAvailableCondition = new LambdaCondition(this, 
            vm => m.ActiveDocument.Highlighting.Type == Highlighting.Xml && 
                !vm.ActiveDocument.IsReadOnly && 
                (vm.License.Kind == LicenseKind.Full || vm.License.TrialDay < 30),
            false);

        MyCommand = new AppCommand(obj => DoSomething(), commandAvailableCondition);
    }

    public ICommand MyCommand { get; } 
    // (all other required properties)
}

또는-만약 당신이 원하는 코드를 조금 더 읽기 쉬운,그래서 그 부분 조건을 다시 사용할 수 있습니다-다음과 같다:

public MyViewModel
{
    private readonly Condition commandAvailableCondition;

    public MyViewModel()
    {
        var highlightingIsXml = new LambdaCondition(this, 
            vm => vm.ActiveDocument.Highlighting.Type == Highlighting.Xml, 
            false);
        var documentIsReadonly = new LambdaCondition(this,
            vm => vm.ActiveDocument.IsReadOnly, 
            false);
        var appIsLicensed = new LambdaCondition(this,
            vm => vm.License.Kind == LicenseKind.Full || this.License.TrialDay < 30,
            false);

        commandAvailableCondition = highlightingIsXml & !documentIsReadonly & appIsLicensed;

        MyCommand = new AppCommand(obj => DoSomething(), commandAvailableCondition);
    }

    public ICommand MyCommand { get; } 
    // (all other required properties)
}

내 라이브러리(또는 더 정확하게, LambdaCondition 클래스)가:

  • 그것은 유의 인스턴스를 모두 구현하는 INotifyPropertyChanged 와 손잡이 변경(예를 들어. 면 ActiveDocument 변경 또는 ActiveDocument.Highlighting 변경 또는 ActiveDocument.Highlighting.Type 변경 등)
  • 그것은 유지의 추적 가능 nulls 길에 어떤 경우에는 반환 기본값(이 경우에, false)
  • 그것은 자동으로 보고서의 변화(하지만 변경)의 가용성하도록 명령 UI 될 수 있습 새로 고침할 때 필요합니다.

질문

어떻게 하나 구현 시나리오를 사용하면 위에서 설명 System.Reactive C#? 그것은 그것을 쉽게 유지하면서 모든 요구 사항에 대해 INotifyPropertyChangednull 방법에 기본값? 당신이 할 수 있는 모든 온전한 가정을 경우 필요합니다.

c# mvvm system.reactive wpf
2021-11-23 15:15:48
1

최고의 응답

0

ReactiveUIReactiveCommand 클래스를 사용하는 사용 IObservable<T> 새로 고침하의 상태를 명령(예:올리 CanExecuteChanged 이벤트 ICommand).

를 참조하시기 바랍 의 예는 어떻게 사용을 제어하는 executability:

var canExecute = this.WhenAnyValue(
    x => x.UserName, x => x.Password,
    (userName, password) => 
        !string.IsNullOrEmpty(userName) && 
        !string.IsNullOrEmpty(password));

var command = ReactiveCommand.CreateFromTask(LogOnAsync, canExecute);
2021-11-24 14:52:33

가 그것을 따르 INotifyPropertyChange 구현에서는 시설 액세스 chain? 그것은 또한 제대로 작동하는 경우 어떤 특성의 null? 할 수 없습을 보여주십시오,어떻게 특정 예제에서 구현된 경우 RX?
Spook

WhenAnyValue 지 않을 방출하는 새로운 값을 때의 UsernamePassword 성 rasises 의 PropertyChanged 이벤트입니다. 무엇이 당신의 구체적인 예는 정확히? 당신은 무엇을 하려고?
mm8

았을 읽어 내 전체 질문? 나는 정확한 상태가 될 것으로 예상되는 지켜: vm => m.ActiveDocument.Highlighting.Type == Highlighting.Xml && !vm.ActiveDocument.IsReadOnly && (vm.License.Kind == LicenseKind.Full || vm.License.TrialDay < 30), 어떤 경우 예를 들어. ActiveDocument null? 니다 RX 핸들을 제대로? 기대 이 경우 조건을 기본값(또는 적어도 기본적으로 거짓)
Spook

는 경우 ActiveDocument을 얻을 것이다 NullReferenceException. 이 함께 할 수 없 RX.
mm8

내 라이브러리에서 나지 않습니다. 즉,다른 사람의 사이에서,이유,내가 관심있는지 여부를 RX 잘 이 작업에 적합합니다.
Spook

다른 언어로

이 페이지는 다른 언어로되어 있습니다

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
ไทย
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................