2013-09-22 17 views
5

Mam kontrolkę tabulacji, która ma 3 strony z zakładkami. Poniżej tej kontrolki karty w tym samym formularzu/widoku, mam 3 formanty obrazu.Jak wyeliminować komunikat Switch?

Na podstawie WybranegoIndeksu zakładki, muszę zmienić krycie poniżej 3 obrazów.

Jak teraz mam coś takiego w SelectionChanged przypadku kontroli zakładka:

switch (Tab.SelectedIndex) 
{ 
    case 0: 
     img1.Opacity= 1; 
     img2.Opacity = 0.5; 
     img3.Opacity = 0.5; 
     break; 
    case 1: 
     img1.Opacity = 0.5; 
     img2.Opacity = 1; 
     img3.Opacity = 0.5; 
     break; 
    case 2: 
     img1.Opacity = 0.5; 
     img2.Opacity = 0.5; 
     img3.Opacity = 1; 
     break; 
} 

Jak mogę usunąć tej instrukcji switch? Który wzór wzoru powinienem tutaj użyć?

+0

Dlaczego usunąć/wymienić wyłącznik? Co nie działa? –

+0

To urządzenie nie jest testowalne. – NoobDeveloper

+2

Tak, jest. Otoczenie sterowane zdarzeniami może być problemem, ale wymaga to większej poprawki. –

Odpowiedz

1

Można użyć wzoru projektu stanu objaśnionego dla instace here. Zdefiniujesz kilka stanów, a następnie pod warunkiem zdecydujesz, które z nich powinny zostać użyte w danym momencie.

Przykład:

abstract class State 
{ 
    abstract vod Apply(Form context); 
} 

class StateOne : State 
{ 
    override void Apply(Form context) 
    { 
     img1.Opacity= 1; 
     img2.Opacity = 0.5; 
     img3.Opacity = 0.5; 
    } 
} 

Można również połączyć go z fabryką metoda projektowania wzoru, który decyduje, które państwo w użyciu.

static class StateFactory 
{ 
    static State GetState(condition) 
    { 
     if(condition == something) 
      return new StateOne(); 
     else ... 
    } 
} 

To nie usunie instrukcji przełączania z kodu, ale będzie co najmniej w rozsądnym miejscu robić rozsądne rzeczy.

Zastosowanie:

StateFactory.GetState(condition).Apply(this); 
+0

Mam pomysł. Czy możesz wyjaśnić to nieco więcej? Więc w SelectionChanged tabcontrol, Jak mogę wiedzieć, który obiekt państwa będę potrzebować? – NoobDeveloper

+1

@Nexus Wydaje mi się, że możesz się pozbyć instrukcji if lub instrukcji swtich, ale możesz umieścić je w miejscu, w którym nie będziesz ich często widzieć, tylko wtedy, gdy potrzebujesz dodać nowy stan. Zaktualizowałem kod dla ciebie metodą Factory. –

+0

+1, ale użyłbym 'Dictionary ' do przechowywania i pobierania stanu (np. '_states [tab.SelectedIndex] .Apply (this)') – Will

1

myślę, że można sobie z tym poradzić w samej XAML za pomocą Triggers.

Także jeśli chcesz mieć tę jednostkę dającej się przetestować, należy użyć MVVM pattern gdzie można zdefiniować properties for SelectedIndex, Opacities w swoim ViewModel i związać je do XAML

+0

EDYCJA: To jest dokładnie to, co zrobiłem. Ale celowo nie opublikowałem tego w moim pytaniu. moje pytanie jest wciąż takie samo. W jaki więc sposób mogę przetestować moją maszynę wirtualną? – NoobDeveloper

+2

jeśli używasz MVVM, możesz napisać przypadki testowe dla właściwości ViewModel dla opaciteis obrazów, które zostaną zmienione po zmianie właściwości selectedindex – Nitin

0

Jeśli masz kilka dowolnych danych, które trzeba przejść w. ... Tak naprawdę nie ma sposobu na łatwe obejście instrukcji switcha (przynajmniej warto to zrobić). Sugerowałbym, przynajmniej pod względem czytelności kodu, użycie enumu. Można zmienić kod w następujący sposób:

switch ((ImageTypes)Tab.SelectedIndex) 
    { 
     case ImageTypes.TypeOne: 
      img1.Opacity= 1; 
      img2.Opacity = 0.5; 
      img3.Opacity = 0.5; 
      break; 
     case ImageTypes.TypeTwo: 
      img1.Opacity = 0.5; 
      img2.Opacity = 1; 
      img3.Opacity = 0.5; 
      break; 
     case ImageTypes.TypeThree: 
      img1.Opacity = 0.5; 
      img2.Opacity = 0.5; 
      img3.Opacity = 1; 
      break; 
    } 
    public enum ImageTypes 
    { 
     TypeOne, 
     TypeTwo, 
     TypeThree 
    } 
1

Ekstrakt i wstrzyknąć. Wyciąg widok zmieniających logikę (przełącznik) do zewnętrznego klasy/metody i wstrzyknąć go do widzenia:

public void HighlightImages(int selection, params Image[] images) 
{ 
    switch (selection) 
    { 
     case 0: 
      images[0].Opacity= 1; 
      images[1].Opacity = 0.5; 
      images[2].Opacity = 0.5; 
      break; 
     case 1: 
      images[0].Opacity = 0.5; 
      images[1].Opacity = 1; 
      images[2].Opacity = 0.5; 
      break; 
     case 2: 
      images[0].Opacity = 0.5; 
      images[1].Opacity = 0.5; 
      images[2].Opacity = 1; 
      break; 
    } 
} 

W wyborze zmienił obsługi wystarczy delegowania obsługi do zatłoczonego Zależność:

private void SelectedIndexChanged(object sender, EventArgs e) 
{ 
    this.highlighter.HighlightImages(Tab.SelectedIndex, img1, img2, img3); 
} 

ten sposób powinno być w stanie przetestować logikę zmiany nieprzejrzystości łatwo, bez konieczności tworzenia instancji kontrolki pełnego widoku.

0

To nie usunie go całkowicie, ponieważ nie ma wiele do zrobienia poza tworzeniem dużego dziedzictwa klasowego, ale byłoby to trochę przesadą w tej sytuacji.

Zamiast tego, można zmniejszyć jego rozmiar tak:

switch (Tab.SelectedIndex) 
{ 
    img1.Opacity = 0.5; 
    img2.Opacity = 0.5; 
    img3.Opacity = 0.5; 

    case 0: 
     img1.Opacity += 0.5; 
     break; 
    case 1: 
     img2.Opacity += 0.5; 
     break; 
    case 2: 
     img3.Opacity += 0.5; 
     break; 
} 

I można zmniejszyć redundancję kodu z metod, dzięki czemu nie trzeba zmieniać 0,5 wszędzie każdym razem, gdy chcesz zmienić krycie. (Umieszczenie 0.5 w stałym byłoby miło zbyt):

switch (Tab.SelectedIndex) 
{ 
    SetInitialOpacity(img1); 
    SetInitialOpacity(img2); 
    SetInitialOpacity(img3); 

    case 0: 
     IncreaseOpacity(img1); 
     break; 
    case 1: 
     IncreaseOpacity(img2); 
     break; 
    case 2: 
     IncreaseOpacity(img3); 
     break; 
} 

private void SetInitialOpacity(Image image) 
{ 
    image.Opacity = 0.5; 
} 


private void IncreaseOpacity(Image image) 
{ 
    image.Opacity += 0.5; 
} 
0

Odnosząc się do tego, co "Jimmy-keen" powiedział, to jest to, co chciałbym przejść do:

public static void HighlightImages(int selection, params Image[] images) 
    { 
     for (int img = 0; img < images.Length; img++) 
     { 
      images[img].Opacity = (img == selection ? 1 : 0.5); 
     } 
    }