2016-11-08 1 views
2

ViewModel이 있는데, Commanding을 사용합니다. 이 ViewModel에서 MediaPlugin 에 액세스하고 싶습니다. 이 플러그인을 사용하여 Initialize()으로 전화해야합니다. async 호출을 사용하기 때문에 타이밍 문제가 있습니다. ViewModel에서 비동기 메서드 호출

내 코드 :이 코드

public ICommand CameraCommand 
{ 
    get { return _cameraCommand ?? (_cameraCommand = new Command(async() => await ExecuteCameraCommand(),() => CanExecuteCameraCommand())); } 
} 

public bool CanExecuteCameraCommand() 
{ 
    // Check if initialized before calling properties 
    if (!this.initialized) 
     InitMedia(); 

    if (!this.initialized || !CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported) 
    { 
     return false; 
    } 
    return true; 
} 

public async Task ExecuteCameraCommand() 
{ 
    // Assure that it is initialized before calling method 
    var file = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions {}); 
    // ... 
} 

private void InitMedia() 
{ 
    CrossMedia.Current.Initialize(); 
    this.initialized = true; 
} 

응용 프로그램이 충돌

과 당신은 어떤 속성을 호출하기 전에 초기화()를 호출해야합니다. Plugin.Media.MediaImplementation.get_IsCameraAvailable에서
()

나는 초기화가 완료되기 전에 호출이 코드

public MyViewModel() 
{ 
    InitData(); 
} 

private async Task InitData() 
{ 
    // ... 
    await InitMedia(); 
} 

private async Task InitMedia() 
{ 
    await CrossMedia.Current.Initialize(); 
    this.initialized = true; 
} 

public bool CanExecuteCameraCommand() 
{ 
    // Check if initialized before calling properties 
    if (!this.initialized) 
     return false; 
    // ... 
} 

CanExecuteCameraCommand()와 같은 생성자의 초기화를 시작합니다. 결과적으로 false이 반환되고 UI의 단추가 비활성화됩니다.

Windows 10 Mobile 장치 (Windows 10 Universal)의 Xamarin.Forms 환경에서이 코드를 테스트하고 있습니다.

+0

MyViewModel의 사용을 공유 할 수 있습니까? –

+0

내 XAML 용으로 ['BindingContext'] (https://developer.xamarin.com/guides/xamarin-forms/xaml/xaml-basics/data_binding_basics/)로 사용됩니다. – testing

+0

예, 초기화하기 전에 BindingContext를 호출 하시겠습니까? xmal 생성자에서 그런 식으로 뭔가? public LoginPage() { vm = new LoginPageViewModel(); BindingContext = vm; InitializeComponent(); } –

답변

2

Minimal, Complete, and Verifiable code example을 제공하지 않았으며 특히 Command 클래스의 구현을 표시하지 않았습니다. 여기서는 Xamarin 기사에서 설명한 Command 클래스를 사용한다고 가정하겠습니다.

  1. 어떤 속성을 취소 (또는 적절한 기본값으로 설정), 초기화의 결과에 따라 어떤 명령을 사용 안 함에 따라 그 :

    보기 모델의 비동기 초기화를위한 기본 전략은 이것이다 초기화의 결과.

  2. 비동기 초기화를 시작하십시오.
  3. 비동기 초기화가 완료 될 때까지 대기하려면 일부 연속 메커니즘 (은 스레드을 차단하지 않음)을 사용하십시오.
  4. 초기화가 완료되면 이전에 비활성화 된 명령을 다시 활성화하고 관련 속성을 업데이트하십시오.

게시 한 코드에 따르면, 가장 중요한 것은 누락되었습니다. # 4 단계입니다. 나는.

private async Task InitMedia() 
{ 
    await CrossMedia.Current.Initialize(); 
    this.initialized = true; 
    _cameraCommand.ChangeCanExecute(); 
} 

Command.ChangeCanExecute() 방법은 CanExecuteChanged 이벤트를 발생시키는 명령에 바인딩 된 컨트롤이 될 수 있도록 : 당신은 당신이 그렇게 할 수있는 편리한 장소가 비록 이전의 장애인 명령을 다시 활성화하기 위해 아무것도하지 않는 CanExecute() 메서드의 결과가 다를 때 알림 메시지가 나타납니다. 초기화가 완료 될 때이 메서드를 호출하면 초기화가 완료된 후에도 단추의 문제를 해결할 수 있습니다.

하나 추가 참고 : 나는 하지 호출 InitMedia() 방법, 또는이 CanExecuteCameraCommand() 방법에서, 전혀 초기화를 할 것입니다.초기화가 비동기 적이기 때문에, 어쨌든 그 메소드에서 돌아 오기 전에 성공적으로 초기화 할 수있는 것과는 달리, 생성자로부터 초기화에 대한 호출을 이미 얻었습니다. ICommand.CanExecute() 구현은 매우 간단해야하며 현재 상태를 확인하고 해당 결과에 따라 필요한 값을 반환하는 데만 제한적으로 사용해야합니다.

위의 질문에 만족하지 못하는 경우 좋은 MCVE를 제공하여 문제를 개선하고 잘못된 세부 사항, 해결 방법, 구체적으로 문제가있는 내용을 설명하십시오. 파악.

+0

'Command'는 ['ICommand' 인터페이스] (https://msdn.microsoft.com/en-us/library/system.windows.input.icommand (v = vs.110) .aspx)를 구현합니다. 나는 너와 같은 결론을 내렸고, 그 상태를 다시 확인해야한다. 결과가 아무데도 사용되지 않기 때문에 뷰 모델의'CanExecuteCameraCommand()'를 다시 호출하는 것은 도움이되지 않습니다. 'ICommand' 인터페이스에는'ChangeCanExecute()'메소드가 정의되어 있지 않습니다. 가능하다면'Command' 클래스를 변경해야합니까? 아니면'CanExecuteChanged' 이벤트를 어떻게 든 트리거 할 수 있습니까? – testing

+0

"ICommand"가 아니라 Xamarin 기사에서 언급 한 것처럼'Command'를 구현해야한다고 생각합니다 ... – testing

+1

_ "이 명령은 ICommand 인터페이스를 구현합니다"_ - 예,하지만 그것은 Command 클래스입니다. (당신이 [Xamarin one] (https://developer.xamarin.com/api/type/Xamarin.Forms.Command/)을 사용한다고 가정) _does_는'ChangeCanExecute()'메소드를 가지고 있습니다. '_cameraCommand' 변수가'ICommand'가 아닌'Command' 타입인지 확인하기 만하면됩니다. _implement_ 무엇이든 할 필요는 없습니다. 이미 사용하고있는'Command' 클래스는 ...'ICommand' 변수에 인스턴스 참조를 저장하여 자신을 제한하지 않도록하십시오. –

관련 문제