2009-07-05 9 views
7

Poruszam się po małej aplikacji sprawdzającej koncepcję. Chodzi głównie o wzmocnienie moich umiejętności MVVM w Silverlight. Natknąłem się dzisiaj na interesujący problem, że nie mogłem wymyślić sposobu rozwiązania problemu MVVM. Nie udało mi się znaleźć niczego istotnego podczas wyszukiwania.Ogólnie preferowana metoda dla ekranu "Oczekiwanie" przy użyciu MVVM i Silverlight

Więc do problemu, mam prostą aplikację typu biznes z back-end bazy danych. Mam widok logowania i dołączony model widoku, który wykona logowanie i raport zakończy się sukcesem lub niepowodzeniem. Nie ma problemu. To, z czego nie byłem jeszcze zadowolony, to sposób na zgłoszenie użytkownikowi ekranu oczekiwania. Tak więc, biorąc pod uwagę mój ekran logowania, użytkownik kliknął Login i opóźnienie trwało kilka sekund, podczas gdy czatowanie z bazą danych zostało zakończone. Chcę to zgłosić i wyłączyć wszelkie interakcje do czasu zakończenia połączenia.

Miałem kilka pomysłów. Najpierw należy powiązać właściwość Cursor z obiektem viewmodel, a maszyna wirtualna może ustawić właściwość IsBusy na wartość true. Problem z tym, że nie mogę wydawać się wiązać z Cursorem dla UserControl (Visual Studio mówi AG_E_RUNTIME_MANAGED_UNKNOWN_ERROR).

Drugi pomysł to posiadanie ekranu oczekiwania. Wiesz, małe kółka obracają się lub jakakolwiek animacja chcesz. I to jest w porządku, ale nie jest dla mnie jasne, w jaki sposób mógłbym uczynić widok, który przełożyłby to przez model poprzez Xaml. Wiem, że mógłbym zdecydowanie podpiąć zdarzenia i poradzić sobie z tym w kodzie. Może to jest droga? Wydaje się, że jest trochę przeciwko ziarnu MVVM.

Byłby zainteresowany większością pomysłów, jak sobie z tym poradzić.

Dziękuję.

Odpowiedz

1

Mamy skończyło się na korzystanie z usług przetwarzania długich żądania eksploatacji. Usługa przyjmuje obciążenie jako delegata, a następnie przekazuje go do usługi BackgroundWorker, jednocześnie otwierając widok "Proszę czekać".

Działa to dobrze, ponieważ pozwala nam kontrolować długich procesów przebiegających przez wszystkich naszych ViewModels w taki sam sposób, z dość prostego interfejsu.

Możesz mieć zdarzenia pochodzące z ViewModel aktualizacji widoku, gdy potrzebujesz opóźnienia, ale następnie musisz mieć ten kod we wszystkich swoich ViewModels, a nie w jednej klasie, które mogą być łatwiejsze w utrzymaniu.

EDYCJA Usługa jest po prostu klasą zarejestrowaną w twoim kontenerze IOC i może być używana przez Twoje ViewModels.

public interface IProcessingService 
{ 
    void Process(Action<BackgroundWorker> action); 
    void Process(Action<BackgroundWorker> action, 
     Action<RunWorkerCompletedEventArgs> finish); 
} 

Za pomocą tego narzędzia ViewModel można zaimplementować coś takiego.

{ 
    var processingService = container.Resolve<IProcessingService>(); 
    processingService.Process(worker => 
    { 
     worker.ReportProgress(0, "Please wait..."); 
     // Do work here 
     worker.ReportProgress(50); 
     // Do more work 
     worker.ReportProgress(100); 
    }); 
} 

ten sposób cały swój kod do wyświetlania powiadomienia postęp jest w klasie implementującej IProcessingService i twoje poglądy pozostają wolne od jakiegokolwiek kodu, który bezpośrednio kontroluje widoku lub jakichkolwiek elementów UI.

+0

Czy mógłbyś trochę się rozwinąć? Kiedy mówisz "skończyło się używaniem usługi", nie podążam za tym. Oczywiście używam usługi wcf do obsługi procesu, SL wywołuje usługę asynchornously, czy mówisz, że istnieje inna usługa, która wywołuje usługę wcf? Bardzo podoba mi się pomysł posiadania ekranu/kodu "oczekiwania" w jednym miejscu, to jest to, o co mi chodzi. – billb

0

Można użyć prototypu Mediatora, który Josh Smith stworzył, aby mieć luźno powiązany system przesyłania komunikatów z VM do V. Maszyna wirtualna mogłaby wypchnąć wiadomość, że jest "zajęta", a widok subskrybuje to "IsBusy" "wiadomość.

Widok może wówczas pokazać właściwą okno aż zostanie odebrany komunikat „IsNotBusy”.

Inną opcją jest przejście do ViewModel w konstruktorze jakiś interfejs jak IDialogProvider który ma metody, aby pokazać okno. Implementacja tego dostawcy będzie zależna od widoku, ale przynajmniej model widoku będzie znał tylko interfejs, a nie konkretną implementację.

public interface IDialogProvider 
{ 
void ShowErrorMessage(string message); 
} 

Mediator Prototype

+0

Dziękuję bardzo za odpowiedź. Kilka razy przeczytałem artykuł mediatora i myślę, że rozumiem. Ale wydaje się to przesadą. Podoba mi się IDialogProvider, ale walczę z sobą o jeden punkt, czy to naprawdę obowiązkiem viewmodelu jest wyświetlanie interfejsu użytkownika? Jeśli nie, to po prostu, czy po prostu mają wydarzenia dla widoku do subskrybowania i czy wyświetlają odpowiednio interfejs użytkownika? – billb

+0

Jeśli używasz widoku do wiązania się z zdarzeniami w maszynie wirtualnej, po co maszyna wirtualna jest na pierwszym miejscu. Dostawca IDialog może być dowolnym interfejsem pozwalającym Viewowi wiedzieć, że wymagane jest okno dialogowe. ShowErrorMessage może zostać zastąpiony przez wszystko, co uznasz za stosowne. –

3

myślę inni mogą być „overthinking” ten jeden ...

Polecam pomocą BusyIndicator w Silverlight Toolkit.

Proste XAML:

<toolkit:BusyIndicator Name="busyBoy" IsBusy="true" BusyContent="Fetching Data..." Margin="6,248,0,0" /> 
Powiązane problemy