Tworzenie zarządzalnych widoków

W artykule Tworzenie widoków omówiono podstawowe kroki niezbędne do utworzenia szkieletu nowego widoku. Przedstawiono również jak taki pusty jeszcze widok poprawnie zarejestrować, aby był zarządzalny w trakcie działania aplikacji (Rejestracja widoków do nawigacji oraz zarządzania wyglądem).

Każdy element (kontrolka) oznaczony unikalnym identyfikatorem LayoutId automatycznie staje się zarządzalny. Zarządzanie polega w większości przypadków na możliwości manipulacji niektórymi właściwościami kontrolek, takimi jak na przykład kolor tła, tekstu, formatowanie czcionki, ustawianie marginesu, szerokości, wysokości, itp. Zostało to również opisane w poprzednim rozdziale.

Zarządzalne elementy zyskują dodatkową cechę w momencie, gdy zostaną one zadeklarowane wewnątrz jednego z dostępnych w aplikacji POS kontenerów: Grid oraz ItemsContainer (z przestrzeni Comarch.POS.Presentation.Core.Controls). Cecha ta to możliwość określania czy i w jakim miejscu element ma się znaleźć w kontenerze.

Zarządzanie elementami w kontenerze ItemsContainer

Dodanie dowolnych kontrolek wewnątrz kontenera ItemsContainer skutkuje domyślną prezentacją ich w kolejności w jakiej zostały zadeklarowane. Specyfika kontenera sprawa, że elementy domyślnie ustawiają się obok siebie poziomo lub pionowo w zależności od ustawionej na kontenerze właściwości Orientation (która oczywiście również może być zarządzalna). Jeżeli kontener będzie posiadał unikalny LayoutId stanie się on zarządzalny oraz pozwoli użytkownikowi na manipulację jego elementami (wszystkie elementy również muszą posiadać swoje unikalne identyfikatory LayoutId). Gdy użytkownik przejdzie do trybu zarządzania widokiem zawierającym ten kontener, będzie mógł za pomocą myszki chwycić dowolną kontrolkę znajdującą się wewnątrz i przeciągnąć ją, zmieniając kolejność wewnętrznych elementów kontenera lub całkiem wyrzucić element z kontenera lub też wrzucić ponownie.

Elementy zadeklarowane wewnątrz kontenera ItemsContainer mogą istnieć tylko i wyłącznie w tym kontenerze. To znaczy, że nie jest możliwe, aby użytkownik mógł wrzucił kontrolkę do innego kontenera. Ograniczenie to znosi kontener typu Grid.

Przykład.

<StackPanel>
      <controls:ItemsContainer core:Layout.Id="ExampleView.ItemsContainer1">
          <TextBlock core:Layout.Id="ExampleView.TextBlock1"/>
          <Button core:Layout.Id="ExampleView.Button1"/>
      </controls:ItemsContainer>
      
      <controls:ItemsContainer core:Layout.Id="ExampleView.ItemsContainer2">
          <TextBlock core:Layout.Id="ExampleView.TextBlock2"/>
          <Button core:Layout.Id="ExampleView.Button2"/>
      </controls:ItemsContainer>
  </StackPanel>

 

Na powyższym przykładzie widzimy widok składający się z dwóch zarządzalnych kontenerów ExampleView.ItemsContainer1 oraz ExampleView.ItemsContainer2. Elementy zadeklarowane wewnątrz tych kontenerów domyślnie wyświetlą się w takiej kolejności w jakiej są zapisane.

Po wejściu w tryb zarządzania tym widokiem użytkownik będzie mógł zmienić kolejność elementów. Będzie mógł wyrzucić element/elementy z kontenerów lub wrzucić je tam ponownie (jeżeli wcześniej zostały przez niego wyrzucone). Nie będzie natomiast mógł przerzucić np. elementu ExampleView.TestBlock1 z kontenera ItemsContainer1 do kontenera ItemsContainer2. Przerzucanie elementów pomiędzy kontenerami nie będzie możliwe.

Zarządzanie elementami w kontenerze Grid

Drugim kontenerem pozwalającym na manipulację jego elementami jest Grid. Kontener ten wymaga zdefiniowania siatki kolumn i wierszy, w których będzie można umieszczać elementy. Siatka ta może zostać określona domyślnie w xaml-u oraz może być zarządzalna przez użytkownika (użytkownik może zmieniać liczbę kolumn i wierszy). Domyślnie każdy element dodany do Grida nie będzie wyświetlany dopóki użytkownik w zarządzaniu nie przeciągnie elementu do wybranej komórki kontenera.

Istnieje możliwość zmiany domyślnej prezentacji elementów składowych, aby działało to tak jak dla kontenera ItemsContainer. W przypadku, gdy właściwość DefaultShowChildren=true, wszystkie elementy domyślnie zostaną zaprezentowane na widoku.

Każdy element zdefiniowany w kontenerze Grid może zostać, podobnie jak w przypadku kontenera typu ItemsContainer, wyrzucony/wrzucony do kontenera. Dodatkowo, jeżeli w kontenerze istnieje inny kontener (Grid lub ItemsContainer) elementy mogę być wrzucone bezpośrednio do zagnieżdżonego kontenera. Dzięki temu możliwe staje się np. przenoszenie kontrolek pomiędzy różnymi kontenerami ItemsContainer.

Przykład.

<controls:Grid core:Layout.Id="ExampleView.BaseGrid">
      <TextBlock core:Layout.Id="ExampleView.TextBlock1"/>
      <Button core:Layout.Id="ExampleView.Button1"/>
      <TextBlock core:Layout.Id="ExampleView.TextBlock2"/>
      <Button core:Layout.Id="ExampleView.Button2"/>
 
      <controls:ItemsContainer core:Layout.Id="ExampleView.ItemsContainer1"/>     
      <controls:ItemsContainer core:Layout.Id="ExampleView.ItemsContainer2" />
  </controls:Grid>

 

W powyższym przykładzie wszystkie kontrolki zostały zdefiniowane bezpośrednio w Gridzie. Teraz podczas pierwszego uruchomienia takiego widoku, zobaczymy pusty widok. Dlatego, że domyślnie Grid nie prezentuje elementów. Natomiast po przejściu do trybu zarządzania będziemy mieć możliwość zdefiniowana siatki Grida (jego kolumn i wierszy) oraz możliwość przeciągnięcia każdej ze zdefiniowanych kontrolek na Grid. Będziemy mogli również przerzucić np. kontrolkę ExampleView.TextBlock1 bezpośrednio do kontenera ExampleView.ItemsContainer1 lub ExampleView.ItemsContainer2, po uprzednim wrzuceniu tych kontenerów na Grid.

Domyślna siatkę Grida możemy również zdefiniować już w xamlu za pomocą właściwości ColumnDefinition oraz RowDefinition.  Żądaną liczbę kolumn lub wierszy ustalamy wprowadzając tyle wartości (konkretna liczba, * lub Auto) ile kolumn/wierszy chcemy uzyskać oddzielając je przecinkami.

I tak np. aby zdefiniować pięć kolumn, z których pierwsza będzie miała szerokość 100, druga automatycznie dobierana, a pozostałe proporcjonalnie po równo dostaną pozostałą przestrzeń, właściwość ColumnDefinition musi mieć wartość: „100,Auto,*,*,*”.

Możemy również zdefiniować domyślne położenie elementów w odpowiedniej komórce Grida za pomocą właściwości Grid.Position. Wartość definiowana jest za pomocą czterech liczb oddzielonych przecinkami, które kolejno oznaczają numer wiersza (numeracja od 0), numer kolumny (numeracja od 0), liczba wierszy (minimum 1) oraz liczba kolumn jakie ma zajmować kontrolka.

Przykład.

<controls:Grid core:Layout.Id="ExampleView.BaseGrid" DefaultShowChildren="True">
        <controls:Grid.Style>
            <Style TargetType="controls:Grid" BasedOn="{StaticResource {x:Type controls:Grid}}">
                <Setter Property="ColumnDefinition" Value="*,*,*" />
                <Setter Property="RowDefinition" Value="*,*,*" />
            </Style>
        </controls:Grid.Style>
 
        <TextBlock core:Layout.Id="ExampleView.TextBlock1" Text="Hello">
            <TextBlock.Style>
                <Style TargetType="TextBlock" BasedOn="{StaticResource {x:Type TextBlock}}">
                    <Setter Property="controls:Grid.Position" Value="1,1,1,1" />
                </Style>
            </TextBlock.Style>
        </TextBlock>
 
    </controls:Grid>

 

Teraz widok składa się z Grida, któremu włączyliśmy domyślnie prezentowanie elementów oraz zdefiniowaliśmy trzy równej szerokości kolumny (szerokość ustalana dynamicznie w zależności od wielkości od szerokości widoku) oraz trzy równej wysokości wiersze (wysokość ustalana dynamicznie tak jak w przypadku szerokości). Kontener składa się z jednego elementu jakim jest TextBlock, któremu ustalono domyślną pozycję w kontenerze na środkową komórkę.

Czy ten artykuł był pomocny?